合并以相同字母开头的pandas DataFrame列

2024-04-26 14:13:40 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个DataFrame

>>> df = pd.DataFrame({'a1':[1,2],'a2':[3,4],'b1':[5,6],'b2':[7,8],'c':[9,0]})
>>> df
   a1  a2  b1  b2  c
0   1   3   5   7  9
1   2   4   6   8  0
>>> 

我想合并(也许不是合并,而是连接)名字的第一个字母相等的列,比如a1和{}等。。。但正如我们所见,有一个c列,它本身没有任何其他类似的列,因此我希望它们不要抛出错误,而是将NaNs添加到它们中。在

我想以一种方式合并,它将把一个宽的DataFrame变成一个长的DataFrame,基本上类似于宽到长的修改。在

我已经有了这个问题的解决方案,但唯一的问题是它非常低效,我想要一个更高效、更快的解决方案(与我的:p不同),我目前有一个for循环和一个tryexcept(呃,听起来已经很糟糕了)代码,例如:

^{pr2}$

我想用更好的代码获得同样的结果。在


Tags: 代码a2dataframedffora1错误字母
3条回答

我建议melt,然后是{}。要解决重复项,需要以cumcounted列为轴心。在

u = df.melt()
u['variable'] = u['variable'].str[0]  # extract the first letter
u.assign(count=u.groupby('variable').cumcount()).pivot('count', 'variable', 'value')

variable    a    b    c
count                  
0         1.0  5.0  9.0
1         2.0  6.0  0.0
2         3.0  7.0  NaN
3         4.0  8.0  NaN

可以改写为

^{pr2}$

如果性能很重要,可以使用pd.concat替代:

from operator import itemgetter

pd.concat({
    k: pd.Series(g.values.ravel()) 
    for k, g in df.groupby(operator.itemgetter(0), axis=1)
}, axis=1)

   a  b    c
0  1  5  9.0
1  3  7  0.0
2  2  6  NaN
3  4  8  NaN

我们可以尝试groupby列(axis=1):

def f(g,a):
    ret = g.stack().reset_index(drop=True)
    ret.name = a
    return ret

pd.concat( (f(g,a) for a,g in df.groupby(df.columns.str[0], axis=1)), axis=1)

输出:

^{pr2}$

使用字典理解:

df = pd.DataFrame({i: pd.Series(x.to_numpy().ravel()) 
                      for i, x in df.groupby(lambda x: x[0], axis=1)})
print (df)
   a  b    c
0  1  5  9.0
1  3  7  0.0
2  2  6  NaN
3  4  8  NaN

相关问题 更多 >