use*_*093 86 python split list dataframe pandas
我有一个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]
Run Code Online (Sandbox Code Playgroud)
我需要使用pandas将这列列表拆分为2列,名为team1和team2
jez*_*ael 162
您可以使用DataFrame
与构造函数lists
通过转换为创建numpy array
通过values
使用tolist
:
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]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
对于新的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
Run Code Online (Sandbox Code Playgroud)
解决方案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
Run Code Online (Sandbox Code Playgroud)
Jos*_*son 29
更简单的解决方案:
pd.DataFrame(df2.teams.tolist(), columns=['team1', 'team2'])
Run Code Online (Sandbox Code Playgroud)
产量,
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
Run Code Online (Sandbox Code Playgroud)
如果要分割一列分隔的字符串而不是列表,则可以类似地执行以下操作:
pd.DataFrame(df.teams.str.split('<delim>', expand=True).values,
columns=['team1', 'team2'])
Run Code Online (Sandbox Code Playgroud)
小智 16
我想推荐一种更高效、Pythonic 的方法。
\n首先将 DataFrame 定义为原始帖子:
\ndf = pd.DataFrame({"teams": [["SF", "NYG"] for _ in range(7)]})\n
Run Code Online (Sandbox Code Playgroud)\n我的解决方案:
\n%%timeit\ndf[\'team1\'], df[\'team2\'] = zip(*list(df[\'teams\'].values))\n>> 761 \xc2\xb5s \xc2\xb1 8.35 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n相比之下,获得最多支持的解决方案:
\n%%timeit\ndf[[\'team1\',\'team2\']] = pd.DataFrame(df.teams.tolist(), index=df.index)\ndf = pd.DataFrame(df[\'teams\'].to_list(), columns=[\'team1\',\'team2\'])\n>> 1.31 ms \xc2\xb1 11.2 \xc2\xb5s per loop\n
Run Code Online (Sandbox Code Playgroud)\n我的解决方案节省了 40% 的时间并且时间短得多。您唯一需要记住的是如何使用 来解压和重塑二维列表zip(*list)
。
Kev*_*ham 11
df2
与使用tolist()
以下解决方案的解决方案不同,该解决方案保留了DataFrame 的索引:
df3 = df2.teams.apply(pd.Series)
df3.columns = ['team1', 'team2']
Run Code Online (Sandbox Code Playgroud)
结果如下:
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
Run Code Online (Sandbox Code Playgroud)
mik*_*ila 10
与提出的解决方案相反,似乎存在语法上更简单的方式,因此更容易记住.我假设该列在数据帧df中称为"meta":
df2 = pd.DataFrame(df['meta'].str.split().values.tolist())
Run Code Online (Sandbox Code Playgroud)
列表理解
一个简单的列表理解实现(我最喜欢的)
df = pd.DataFrame([pd.Series(x) for x in df.teams])
df.columns = ['team_{}'.format(x+1) for x in df.columns]
Run Code Online (Sandbox Code Playgroud)
输出时序:
CPU times: user 0 ns, sys: 0 ns, total: 0 ns
Wall time: 2.71 ms
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
以前的解决方案对我不起作用,因为我nan
在我的dataframe
. 在我的情况下df2[['team1','team2']] = pd.DataFrame(df2.teams.values.tolist(), index= df2.index)
产生:
object of type 'float' has no len()
Run Code Online (Sandbox Code Playgroud)
我使用列表理解来解决这个问题。这是可复制的示例:
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
Run Code Online (Sandbox Code Playgroud)
输出:
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
Run Code Online (Sandbox Code Playgroud)
用列表理解来解决,
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
Run Code Online (Sandbox Code Playgroud)
产量:
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
Run Code Online (Sandbox Code Playgroud)
这是使用df.transform
and的另一个解决方案df.set_index
:
>>> from operator import itemgetter
>>> df['teams'].transform({'item1': itemgetter(0), 'item2': itemgetter(1)})
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
Run Code Online (Sandbox Code Playgroud)
当然可以概括为:
>>> indices = range(len(df['teams'][0]))
>>> df['teams'].transform({f'team{i+1}': itemgetter(i) for i in indices})
team1 team2
0 SF NYG
1 SF NYG
2 SF NYG
3 SF NYG
4 SF NYG
5 SF NYG
6 SF NYG
Run Code Online (Sandbox Code Playgroud)
这种方法具有提取所需索引的额外好处:
>>> df
teams
0 [SF, NYG, XYZ, ABC]
1 [SF, NYG, XYZ, ABC]
2 [SF, NYG, XYZ, ABC]
3 [SF, NYG, XYZ, ABC]
4 [SF, NYG, XYZ, ABC]
5 [SF, NYG, XYZ, ABC]
6 [SF, NYG, XYZ, ABC]
>>> indices = [0, 2]
>>> df['teams'].transform({f'team{i+1}': itemgetter(i) for i in indices})
team1 team3
0 SF XYZ
1 SF XYZ
2 SF XYZ
3 SF XYZ
4 SF XYZ
5 SF XYZ
6 SF XYZ
Run Code Online (Sandbox Code Playgroud)
小智 5
根据前面的答案,这是另一个解决方案,它返回与 df2.teams.apply(pd.Series) 相同的结果,但运行时间要快得多:
\n\npd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)\n
Run Code Online (Sandbox Code Playgroud)\n\n时间:
\n\nIn [1]:\nimport pandas as pd\nd1 = {'teams': [['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],\n ['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG'],['SF', 'NYG']]}\ndf2 = pd.DataFrame(d1)\ndf2 = pd.concat([df2]*1000).reset_index(drop=True)\n\nIn [2]: %timeit df2['teams'].apply(pd.Series)\n\n8.27 s \xc2\xb1 2.73 s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1 loop each)\n\nIn [3]: %timeit pd.DataFrame([{x: y for x, y in enumerate(item)} for item in df2['teams'].values.tolist()], index=df2.index)\n\n35.4 ms \xc2\xb1 5.22 ms per loop (mean \xc2\xb1 std. dev. of 7 runs, 10 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n