通过熊猫中的字符串列编号名称聚合列值

时间:2019-04-11 10:53:42

标签: python pandas

我有一张桌子

enter image description here

我想对属于同一类h。*的列的值求和。因此,我的决赛桌将如下所示:

enter image description here

是否可以按字符串列名称进行汇总?

谢谢您的任何建议!

2 个答案:

答案 0 :(得分:1)

首先使用lambda函数选择参数为axis=1的前3个字符或以相似的方式索引列名称并聚合sum

df1 = df.set_index('object')

df2 = df1.groupby(lambda x: x[:3], axis=1).sum().reset_index()

或者:

df1 = df.set_index('object')

df2 = df1.groupby(df1.columns.str[:3], axis=1).sum().reset_index()

示例

np.random.seed(123)

cols = ['object', 'h.1.1','h.1.2','h.1.3','h.1.4','h.1.5',
        'h.2.1','h.2.2','h.2.3','h.2.4','h.3.1','h.3.2','h.3.3']
df = pd.DataFrame(np.random.randint(10, size=(4, 13)), columns=cols)
print (df)
   object  h.1.1  h.1.2  h.1.3  h.1.4  h.1.5  h.2.1  h.2.2  h.2.3  h.2.4  \
0       2      2      6      1      3      9      6      1      0      1   
1       9      3      4      0      0      4      1      7      3      2   
2       4      8      0      7      9      3      4      6      1      5   
3       8      3      5      0      2      6      2      4      4      6   

   h.3.1  h.3.2  h.3.3  
0      9      0      0  
1      4      7      2  
2      6      2      1  
3      3      0      6 

df1 = df.set_index('object')
df2 = df1.groupby(lambda x: x[:3], axis=1).sum().reset_index()
print (df2)
   object  h.1  h.2  h.3
0       2   21    8    9
1       9   11   13   13
2       4   27   16    9
3       8   16   16    9

答案 1 :(得分:1)

上面的解决方案效果很好,但是如果h.X超过一位数,则很容易受到攻击。我建议以下内容:

样本数据:

cols = ['h.%d.%d' %(i, j) for i in range(1, 11) for j in range(1, 11)]
df = pd.DataFrame(np.random.randint(10, size=(4, len(cols))), columns=cols, index=['p_%d'%p for p in range(4)])

建议的解决方案:

new_df = df.groupby(df.columns.str.split('.').str[1], axis=1).sum()
new_df.columns = 'h.' + new_df.columns # the columns are originallly numbered 1, 2, 3. This brings it back to h.1, h.2, h.3

替代解决方案:

遍历多索引可能比较复杂,但是在其他地方处理此数据时可能很有用。

df.columns = df.columns.str.split('.', expand=True) # Transform into a multiindex
new_df = df.sum(axis = 1, level=[0,1])
new_df.columns = new_df.columns.get_level_values(0) + '.' + new_df.columns.get_level_values(1) # Rename columns