我正在寻找一种以下列方式在pandas中堆叠数据帧的方法:
id val
id01 ['a', 'b']
id02 ['b']
id03 []
id04 ['a','c']
为:
id01 'a'
'b'
id02 'b'
id04 'a'
'c'
答案 0 :(得分:1)
如果希望Series
与MultiIndex
一起使用stack
与DataFrame
contructor:
s = pd.DataFrame(df['val'].values.tolist(), index=df['id']).stack()
print (s)
id
id01 0 a
1 b
id02 0 b
id04 0 a
1 c
dtype: object
如果需要DataFrame
添加双reset_index
- 首先删除第二级MultiIndex
,第二级为索引创建列:
df = (pd.DataFrame(df['val'].values.tolist(), index=df['id'])
.stack()
.reset_index(level=1, drop=True)
.reset_index(name='val'))
print (df)
id val
0 id01 a
1 id01 b
2 id02 b
3 id04 a
4 id04 c
如果需要替换重复值,请使用loc
+ duplicated
:
df.loc[df['id'].duplicated(), 'id'] = ''
print (df)
id val
0 id01 a
1 b
2 id02 b
3 id04 a
4 c
答案 1 :(得分:0)
对于一个可以解决的问题,@jezrael's solution很好。
如果要考虑效率问题,建立新数据框通常比stack
更有效:
import pandas as pd, numpy as np
from itertools import chain
df = pd.DataFrame({'id': ['id01', 'id02', 'id03', 'id04'],
'val': [['a', 'b'], ['b'], [], ['a', 'c']]})
lens = list(map(len, df['val']))
res = pd.DataFrame({'id': np.repeat(df['id'].values, lens),
'val': list(chain.from_iterable(df['val']))})
print(res)
# id val
# 0 id01 a
# 1 id01 b
# 2 id02 b
# 3 id04 a
# 4 id04 c
效果基准
import pandas as pd, numpy as np
from itertools import chain
df = pd.DataFrame({'id': ['id01', 'id02', 'id03', 'id04'],
'val': [['a', 'b'], ['b'], [], ['a', 'c']]})
df = pd.concat([df]*100000)
def jp(df):
lens = list(map(len, df['val']))
res = pd.DataFrame({'id': np.repeat(df['id'].values, lens),
'val': list(chain.from_iterable(df['val']))})
return res
def jez(df):
return (pd.DataFrame(df['val'].values.tolist(), index=df['id'])
.stack()
.reset_index(level=1, drop=True)
.reset_index(name='val'))
%timeit jp(df) # 137 ms per loop
%timeit jez(df) # 197 ms per loop