Pandas 一系列列表到一个系列
Pandas Series of lists to one series
我有一个 Pandas 系列字符串列表:
0 [slim, waist, man]
1 [slim, waistline]
2 [santa]
如您所见,列表因长度而异。我想要一种有效的方法将其折叠成一个系列
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
我知道我可以使用
分解列表
series_name.split(' ')
但我很难将这些字符串放回一个列表中。
谢谢!
您可以像下面这样使用列表连接运算符 -
lst1 = ['hello','world']
lst2 = ['bye','world']
newlst = lst1 + lst2
print(newlst)
>> ['hello','world','bye','world']
或者您可以使用 list.extend()
函数,如下所示 -
lst1 = ['hello','world']
lst2 = ['bye','world']
lst1.extend(lst2)
print(lst1)
>> ['hello', 'world', 'bye', 'world']
使用 extend
函数的好处是它可以处理多种类型,而 concatenation
运算符仅在 LHS 和 RHS 均为列表时才有效。
extend
函数的其他例子-
lst1.extend(('Bye','Bye'))
>> ['hello', 'world', 'Bye', 'Bye']
您可以尝试使用 itertools.chain 简单地展平列表:
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
您基本上只是想在此处展平嵌套列表。
您应该能够迭代系列的元素:
slist =[]
for x in series:
slist.extend(x)
或更巧妙(但更难理解)的列表理解:
slist = [st for row in s for st in row]
这是一个仅使用 pandas 个函数的简单方法:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
然后
s.apply(pd.Series).stack().reset_index(drop=True)
给出了想要的输出。在某些情况下,您可能希望保存原始索引并添加第二级索引来索引嵌套元素,例如
0 0 slim
1 waist
2 man
1 0 slim
1 waistline
2 0 santa
如果这是您想要的,只需从链中省略 .reset_index(drop=True)
。
series_name.sum()
正是您所需要的。请确保它是一系列列表,否则您的值将被连接(如果是字符串)或添加(如果是 int)
可以使用此函数进行展平和反展平
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
去扁平化:
def unflatten(flat_df, col):
flat_df.groupby(level=0).agg({**{c:'first' for c in flat_df.columns}, col: list})
展开后我们得到相同的数据帧,除了列顺序:
(df.sort_index(axis=1) == unflatten(flatten(df)).sort_index(axis=1)).all().all()
>> True
在 pandas 版本 0.25.0
中出现了 series and dataframes 的新方法 'explode'。旧版本没有这样的方法。
它有助于构建您需要的结果。
例如你有这样的系列:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
那你就可以使用
s.explode()
得到这样的结果:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
如果是数据框:
df = pd.DataFrame({
's': pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']
]),
'a': 1
})
你将拥有这样的DataFrame:
s a
0 [slim, waist, man] 1
1 [slim, waistline] 1
2 [santa] 1
在 s
列上应用爆炸:
df.explode('s')
会给你这样的结果:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
如果您的系列包含空列表
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa'],
[]
])
然后 运行 explode
将为空列表引入 NaN 值,如下所示:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
3 NaN
如果不需要,您可以dropna方法调用:
s.explode().dropna()
得到这个结果:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
Dataframes 也有 dropna 方法:
df = pd.DataFrame({
's': pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa'],
[]
]),
'a': 1
})
运行 explode
没有 dropna:
df.explode('s')
结果为:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
3 NaN 1
与 dropna:
df.explode('s').dropna(subset=['s'])
结果:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
您也可以试试:
combined = []
for i in s.index:
combined = combined + s.iloc[i]
print(combined)
s = pd.Series(combined)
print(s)
输出:
['slim', 'waist', 'man', 'slim', 'waistline', 'santa']
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
dtype: object
如果您的 pandas
版本太旧而无法使用 series_name.explode()
,这也应该有效:
from itertools import chain
pd.Series(
chain.from_iterable(
value
for i, value
in series_name.iteritems()
)
)
我有一个 Pandas 系列字符串列表:
0 [slim, waist, man]
1 [slim, waistline]
2 [santa]
如您所见,列表因长度而异。我想要一种有效的方法将其折叠成一个系列
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
我知道我可以使用
分解列表series_name.split(' ')
但我很难将这些字符串放回一个列表中。
谢谢!
您可以像下面这样使用列表连接运算符 -
lst1 = ['hello','world']
lst2 = ['bye','world']
newlst = lst1 + lst2
print(newlst)
>> ['hello','world','bye','world']
或者您可以使用 list.extend()
函数,如下所示 -
lst1 = ['hello','world']
lst2 = ['bye','world']
lst1.extend(lst2)
print(lst1)
>> ['hello', 'world', 'bye', 'world']
使用 extend
函数的好处是它可以处理多种类型,而 concatenation
运算符仅在 LHS 和 RHS 均为列表时才有效。
extend
函数的其他例子-
lst1.extend(('Bye','Bye'))
>> ['hello', 'world', 'Bye', 'Bye']
您可以尝试使用 itertools.chain 简单地展平列表:
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
您基本上只是想在此处展平嵌套列表。
您应该能够迭代系列的元素:
slist =[]
for x in series:
slist.extend(x)
或更巧妙(但更难理解)的列表理解:
slist = [st for row in s for st in row]
这是一个仅使用 pandas 个函数的简单方法:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
然后
s.apply(pd.Series).stack().reset_index(drop=True)
给出了想要的输出。在某些情况下,您可能希望保存原始索引并添加第二级索引来索引嵌套元素,例如
0 0 slim
1 waist
2 man
1 0 slim
1 waistline
2 0 santa
如果这是您想要的,只需从链中省略 .reset_index(drop=True)
。
series_name.sum()
正是您所需要的。请确保它是一系列列表,否则您的值将被连接(如果是字符串)或添加(如果是 int)
可以使用此函数进行展平和反展平
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
去扁平化:
def unflatten(flat_df, col):
flat_df.groupby(level=0).agg({**{c:'first' for c in flat_df.columns}, col: list})
展开后我们得到相同的数据帧,除了列顺序:
(df.sort_index(axis=1) == unflatten(flatten(df)).sort_index(axis=1)).all().all()
>> True
在 pandas 版本 0.25.0
中出现了 series and dataframes 的新方法 'explode'。旧版本没有这样的方法。
它有助于构建您需要的结果。
例如你有这样的系列:
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']])
那你就可以使用
s.explode()
得到这样的结果:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
如果是数据框:
df = pd.DataFrame({
's': pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa']
]),
'a': 1
})
你将拥有这样的DataFrame:
s a
0 [slim, waist, man] 1
1 [slim, waistline] 1
2 [santa] 1
在 s
列上应用爆炸:
df.explode('s')
会给你这样的结果:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
如果您的系列包含空列表
import pandas as pd
s = pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa'],
[]
])
然后 运行 explode
将为空列表引入 NaN 值,如下所示:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
3 NaN
如果不需要,您可以dropna方法调用:
s.explode().dropna()
得到这个结果:
0 slim
0 waist
0 man
1 slim
1 waistline
2 santa
Dataframes 也有 dropna 方法:
df = pd.DataFrame({
's': pd.Series([
['slim', 'waist', 'man'],
['slim', 'waistline'],
['santa'],
[]
]),
'a': 1
})
运行 explode
没有 dropna:
df.explode('s')
结果为:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
3 NaN 1
与 dropna:
df.explode('s').dropna(subset=['s'])
结果:
s a
0 slim 1
0 waist 1
0 man 1
1 slim 1
1 waistline 1
2 santa 1
您也可以试试:
combined = []
for i in s.index:
combined = combined + s.iloc[i]
print(combined)
s = pd.Series(combined)
print(s)
输出:
['slim', 'waist', 'man', 'slim', 'waistline', 'santa']
0 slim
1 waist
2 man
3 slim
4 waistline
5 santa
dtype: object
如果您的 pandas
版本太旧而无法使用 series_name.explode()
,这也应该有效:
from itertools import chain
pd.Series(
chain.from_iterable(
value
for i, value
in series_name.iteritems()
)
)