我的数据框如下所示:
mydata = [{'col_A' : 'A', 'col_B': [1,2,3]},
{'col_A' : 'B', 'col_B': [7,8]}]
pd.DataFrame(mydata)
col_A col_B
A [1, 2, 3]
B [7, 8]
如何拆分列表中的值并创建如下所示的数据框:
col_A col_B
A 1
A 2
A 3
B 7
B 8
答案 0 :(得分:1)
试试这个:
pd.DataFrame([{'col_A':row['col_A'], 'col_B':val}
for ind, row in df.iterrows()
for val in row['col_B']])
你也可以使用apply()函数做一些聪明的事情,但是在我的脑海中,我可以想到如何。
答案 1 :(得分:1)
以下是使用apply
的解决方案:
df['col_B'].apply(pd.Series).set_index(df['col_A']).stack().reset_index(level=0)
col_A 0
0 A 1
1 A 2
2 A 3
3 B 7
4 B 8
答案 2 :(得分:1)
如果您的DataFrame
很大,最快的就是DataFrame constructor
使用stack
并加倍reset_index
:
print pd.DataFrame(x for x in df['col_B']).set_index(df['col_A']).stack()
.reset_index(drop=True, level=1).reset_index().rename(columns={0:'col_B'})
<强>测试强>:
import pandas as pd
mydata = [{'col_A' : 'A', 'col_B': [1,2,3]},
{'col_A' : 'B', 'col_B': [7,8]}]
df = pd.DataFrame(mydata)
print df
df = pd.concat([df]*1000).reset_index(drop=True)
print pd.DataFrame(x for x in df['col_B']).set_index(df['col_A']).stack().reset_index(drop=True, level=1).reset_index().rename(columns={0:'col_B'})
print pd.DataFrame(x for x in df['col_B']).set_index(df['col_A']).stack().reset_index().drop('level_1', axis=1).rename(columns={0:'col_B'})
print df['col_B'].apply(pd.Series).set_index(df['col_A']).stack().reset_index().drop('level_1', axis=1).rename(columns={0:'col_B'})
print pd.DataFrame([{'col_A':row['col_A'], 'col_B':val} for ind, row in df.iterrows() for val in row['col_B']])
<强>时序强>:
In [1657]: %timeit pd.DataFrame(x for x in df['col_B']).set_index(df['col_A']).stack().reset_index().drop('level_1', axis=1).rename(columns={0:'col_B'})
100 loops, best of 3: 4.01 ms per loop
In [1658]: %timeit pd.DataFrame(x for x in df['col_B']).set_index(df['col_A']).stack().reset_index(drop=True, level=1).reset_index().rename(columns={0:'col_B'})
100 loops, best of 3: 3.09 ms per loop
In [1659]: %timeit pd.DataFrame([{'col_A':row['col_A'], 'col_B':val} for ind, row in df.iterrows() for val in row['col_B']])
10 loops, best of 3: 153 ms per loop
In [1660]: %timeit df['col_B'].apply(pd.Series).set_index(df['col_A']).stack().reset_index().drop('level_1', axis=1).rename(columns={0:'col_B'})
1 loops, best of 3: 357 ms per loop