Nesting (explosion) panda series
发布于 2021-01-29 17:51:30
我有:
df = pd.DataFrame({'col1': ['asdf', 'xy', 'q'], 'col2': [1, 2, 3]})
col1 col2
0 asdf 1
1 xy 2
2 q 3
我想从in中的字符串中提取每个字母的“组合乘积”,并将in中的col1
每个elementwise int提取col2
。即:
col1 col2
0 a 1
1 s 1
2 d 1
3 f 1
4 x 2
5 y 2
6 q 3
当前方法:
from itertools import product
pieces = []
for _, s in df.iterrows():
letters = list(s.col1)
prods = list(product(letters, [s.col2]))
pieces.append(pd.DataFrame(prods))
pd.concat(pieces)
还有更有效的解决方法吗?
关注者
0
被浏览
43
1 个回答
-
使用
list
+str.join
和np.repeat
-pd.DataFrame( { 'col1' : list(''.join(df.col1)), 'col2' : df.col2.values.repeat(df.col1.str.len(), axis=0) }) col1 col2 0 a 1 1 s 1 2 d 1 3 f 1 4 x 2 5 y 2 6 q 3
无需更改 任何 解决方案即可轻松实现针对 任意数量列的 通用解决方案-
i = list(''.join(df.col1)) j = df.drop('col1', 1).values.repeat(df.col1.str.len(), axis=0) df = pd.DataFrame(j, columns=df.columns.difference(['col1'])) df.insert(0, 'col1', i) df col1 col2 0 a 1 1 s 1 2 d 1 3 f 1 4 x 2 5 y 2 6 q 3
性能
df = pd.concat([df] * 100000, ignore_index=True) # MaxU's solution %%timeit df.col1.str.extractall(r'(.)') \ .reset_index(level=1, drop=True) \ .join(df['col2']) \ .reset_index(drop=True) 1 loop, best of 3: 1.98 s per loop # piRSquared's solution %%timeit pd.DataFrame( [[x] + b for a, *b in df.values for x in a], columns=df.columns ) 1 loop, best of 3: 1.68 s per loop # Wen's solution %%timeit v = df.col1.apply(list) pd.DataFrame({'col1':np.concatenate(v.values),'col2':df.col2.repeat(v.apply(len))}) 1 loop, best of 3: 835 ms per loop # Alexander's solution %%timeit pd.DataFrame([(letter, i) for letters, i in zip(df['col1'], df['col2']) for letter in letters], columns=df.columns) 1 loop, best of 3: 316 ms per loop %%timeit pd.DataFrame( { 'col1' : list(''.join(df.col1)), 'col2' : df.col2.values.repeat(df.col1.str.len(), axis=0) }) 10 loops, best of 3: 124 ms per loop
我尝试对Vaishali进行计时,但是在此数据集上花费的时间太长。