J'ai une Pandas Série de listes de chaînes:
0 [slim, waist, man]
1 [slim, waistline]
2 [santa]
Comme vous pouvez le voir, les listes varient selon la longueur. Je veux un moyen efficace de réduire cela en une seule série
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
Je sais que je peux briser les listes en utilisant
series_name.split(' ')
Mais j'ai du mal à remettre ces cordes dans une seule liste.
Merci!
Vous essayez simplement d'aplanir une liste imbriquée ici.
Vous devriez juste pouvoir parcourir les éléments de la série:
slist =[]
for x in series:
slist.extend(x)
ou une compréhension plus subtile (mais plus difficile à comprendre) de la liste:
slist = [st for row in s for st in row]
Voici une méthode simple utilisant uniquement les fonctions pandas:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
Ensuite
s.apply(pd.Series).stack().reset_index(drop=True)
donne la sortie souhaitée. Dans certains cas, vous souhaiterez peut-être enregistrer l'index d'origine et ajouter un deuxième niveau pour indexer les éléments imbriqués, par exemple.
0 0 slim
1 waist
2 man
1 0 slim
1 waistline
2 0 santa
Si c'est ce que vous voulez, omettez simplement .reset_index(drop=True)
de la chaîne.
series_name.sum()
fait exactement ce dont vous avez besoin. Assurez-vous qu'il s'agit d'une série de listes, sinon vos valeurs seront concaténées (si chaîne) ou ajoutées (si int)
Vous pouvez essayer d'utiliser itertools.chain pour aplatir simplement les listes:
In [70]: from itertools import chain
In [71]: import pandas as pnd
In [72]: s = pnd.Series([['slim', 'waist', 'man'], ['slim', 'waistline'], ['santa']])
In [73]: s
Out[73]:
0 [slim, waist, man]
1 [slim, waistline]
2 [santa]
dtype: object
In [74]: new_s = pnd.Series(list(chain(*s.values)))
In [75]: new_s
Out[75]:
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
dtype: object
Le problème avec series_name.explode()
est que chaque []
ajoute NaN
.
Pour éviter cela, j'ai trouvé un autre moyen:
from itertools import chain
pd.Series(
chain.from_iterable(
value
for i, value
in series_name.iteritems()
)
)
L'aplatissement et le non-aplatissement peuvent être effectués à l'aide de cette fonction
def flatten(df, col):
col_flat = pd.DataFrame([[i, x] for i, y in df[col].apply(list).iteritems() for x in y], columns=['I', col])
col_flat = col_flat.set_index('I')
df = df.drop(col, 1)
df = df.merge(col_flat, left_index=True, right_index=True)
return df
Non aplatissant:
def unflatten(flat_df, col):
flat_df.groupby(level=0).agg({**{c:'first' for c in flat_df.columns}, col: list})
Après aplatissement, nous obtenons la même trame de données, sauf l'ordre des colonnes:
(df.sort_index(axis=1) == unflatten(flatten(df)).sort_index(axis=1)).all().all()
>> True
Dans pandas version 0.25.0
est apparu une nouvelle méthode 'exploser' pour série et dataframes . Les anciennes versions n'ont pas une telle méthode.
Cela aide à obtenir le résultat dont vous avez besoin.
Par exemple, vous avez une telle série:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
Ensuite, vous pouvez utiliser
s.explode()
Pour obtenir un tel résultat:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
En cas de trame de données:
df = pd.DataFrame({
's': pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']
]),
'a': 1
})
Vous aurez un tel DataFrame:
s a
0 [slim, waist, man] 1
1 [slim, waistline] 1
2 [santa] 1
Application de l'éclatement sur la colonne s
:
df.explode('s')
Vous donnera un tel résultat:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
Vous pouvez également essayer:
combined = []
for i in s.index:
combined = combined + s.iloc[i]
print(combined)
s = pd.Series(combined)
print(s)
production:
['slim', 'waist', 'man', 'slim', 'waistline', 'santa']
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
dtype: object
Vous pouvez utiliser l'opérateur de concaténation de liste comme ci-dessous -
lst1 = ['hello','world']
lst2 = ['bye','world']
newlst = lst1 + lst2
print(newlst)
>> ['hello','world','bye','world']
Ou vous pouvez utiliser la fonction list.extend()
comme ci-dessous -
lst1 = ['hello','world']
lst2 = ['bye','world']
lst1.extend(lst2)
print(lst1)
>> ['hello', 'world', 'bye', 'world']
Les avantages de l'utilisation de la fonction extend
sont qu'elle peut fonctionner sur plusieurs types, alors que l'opérateur concatenation
ne fonctionnera que si LHS et RHS sont des listes.
Autres exemples de fonction extend
-
lst1.extend(('Bye','Bye'))
>> ['hello', 'world', 'Bye', 'Bye']