我有一个pandas dataFrame,其中一列如下所示:
`
In [207]:df2.teams
Out[207]:
0 [SF, NYG]
1 [SF, NYG]
2 [SF, NYG]
3 [SF, NYG]
4 [SF, NYG]
5 [SF, NYG]
6 [SF, NYG]
7 [SF, NYG]
`
我需要使用pandas
将此列列表拆分为2列,名为team1和team2答案 0 :(得分:118)
您可以使用create table restaurants (
...,
ratings integer[],
...
);
构建函数与DataFrame
创建的lists
values
tolist
使用numpy array
:
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
print (df2)
teams
0 [SF, NYG]
1 [SF, NYG]
2 [SF, NYG]
3 [SF, NYG]
4 [SF, NYG]
5 [SF, NYG]
6 [SF, NYG]
df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
print (df2)
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 [SF, NYG] SF NYG
3 [SF, NYG] SF NYG
4 [SF, NYG] SF NYG
5 [SF, NYG] SF NYG
6 [SF, NYG] SF NYG
对于新的DataFrame
:
df3 = pd.DataFrame(df2['teams'].values.tolist(), columns=['team1','team2'])
print (df3)
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
apply(pd.Series)
的解决方案非常缓慢:
#7k rows
df2 = pd.concat([df2]*1000).reset_index(drop=True)
In [89]: %timeit df2['teams'].apply(pd.Series)
1 loop, best of 3: 1.15 s per loop
In [90]: %timeit pd.DataFrame(df2['teams'].values.tolist(), columns=['team1','team2'])
1000 loops, best of 3: 820 µs per loop
答案 1 :(得分:14)
更简单的解决方案:
pd.DataFrame(df2.teams.tolist(), columns=['team1', 'team2'])
产量,
team1 team2
-------------
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
7 SF NYG
如果你想拆分一列分隔的字符串而不是列表,你可以这样做:
pd.DataFrame(df.teams.str.split('<delim>', expand=True).values,
columns=['team1', 'team2'])
答案 2 :(得分:11)
与使用df2
的解决方案不同,该解决方案保留了tolist()
DataFrame的索引:
df3 = df2.teams.apply(pd.Series)
df3.columns = ['team1', 'team2']
结果如下:
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
答案 3 :(得分:7)
与提议的解决方案相反,似乎存在语法上更简单的方式,因此更容易记住。我假设该列被称为“meta”#meta;在数据框df中:
df2 = pd.DataFrame(df['meta'].str.split().values.tolist())
答案 4 :(得分:5)
由于我的nan
中有dataframe
个观察结果,因此上述解决方案对我不起作用。就我而言,df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
产生:
object of type 'float' has no len()
我使用列表理解来解决这个问题。这里是可复制的示例:
import pandas as pd
import numpy as np
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2.loc[2,'teams'] = np.nan
df2.loc[4,'teams'] = np.nan
df2
输出:
teams
0 [SF, NYG]
1 [SF, NYG]
2 NaN
3 [SF, NYG]
4 NaN
5 [SF, NYG]
6 [SF, NYG]
df2['team1']=np.nan
df2['team2']=np.nan
解决列表理解问题
for i in [0,1]:
df2['team{}'.format(str(i+1))]=[k[i] if isinstance(k,list) else k for k in df2['teams']]
df2
产量:
teams team1 team2
0 [SF, NYG] SF NYG
1 [SF, NYG] SF NYG
2 NaN NaN NaN
3 [SF, NYG] SF NYG
4 NaN NaN NaN
5 [SF, NYG] SF NYG
6 [SF, NYG] SF NYG
答案 5 :(得分:3)
列表理解
具有列表理解功能的简单实现(我的最爱)
df = pd.DataFrame([pd.Series(x) for x in df.teams])
df.columns = ['team_{}'.format(x+1) for x in df.columns]
输出定时:
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 2.71 ms
输出:
team_1 team_2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
答案 6 :(得分:2)
这是使用df.transform
和df.set_index
的另一种解决方案:
>>> (df['teams']
.transform([lambda x:x[0], lambda x:x[1]])
.set_axis(['team1','team2'],
axis=1,
inplace=False)
)
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
答案 7 :(得分:1)
根据先前的回答,这是另一个解决方案,它以更快的运行时间返回与df2.teams.apply(pd.Series)相同的结果:
pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)
时间:
In [1]:
import pandas as pd
d1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],
['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}
df2 = pd.DataFrame(d1)
df2 = pd.concat([df2]*1000).reset_index(drop=True)
In [2]: %timeit df2['teams'].apply(pd.Series)
8.27 s ± 2.73 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [3]: %timeit pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)
35.4 ms ± 5.22 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)