Pandas数据框按行求和

10

我有一个记录的DataFrame,看起来像这样:

stocks = pd.Series(['A', 'A', 'B', 'C', 'C'], name = 'stock')
positions = pd.Series([ 100, 200, 300, 400, 500], name = 'positions')
same1 = pd.Series(['AA', 'AA', 'BB', 'CC', 'CC'], name = 'same1')
same2 = pd.Series(['AAA', 'AAA', 'BBB', 'CCC', 'CCC'], name = 'same2')
diff = pd.Series(['A1', 'A2', 'B3' ,'C1', 'C2'], name = 'different')
df = pd.DataFrame([stocks, same1, positions, same2, diff]).T
df

这将生成一个类似于pandas DataFrame的数据框,如下所示:
      stock same1 positions same2 different
0     A    AA       100   AAA        A1
1     A    AA       200   AAA        A2
2     B    BB       300   BBB        B3
3     C    CC       400   CCC        C1
4     C    CC       500   CCC        C2

我对“不同”的列中的数据不感兴趣,想要对唯一的其他列进行位置求和。我目前的做法是:

df.groupby(['stock','same1','same2'])['positions'].sum()

这将会得到:

stock  same1  same2
A      AA     AAA      300
B      BB     BBB      300
C      CC     CCC      900
Name: positions

问题是这是一个具有多索引的pd.Series。目前,我在迭代它以重新构建DataFrame。我确信我错过了一种方法。基本上,我想从DataFrame中删除1列,然后“重建”它,使得一列被求和,其余字段(相同的字段)保持不变。
如果存在空位置,此groupby方法将会出错。因此,我目前使用一个复杂的DataFrame迭代来构建一个新的DataFrame。是否有更好的方法?
1个回答

10

步骤1. 使用[['positions']]而不是['positions']:

In [30]: df2 = df.groupby(['stock','same1','same2'])[['positions']].sum()

In [31]: df2 
Out[31]: 

                   positions
stock same1 same2               
A     AA    AAA          300 
B     BB    BBB          300 
C     CC    CCC          900 

第二步,然后使用reset_index将索引移回到列中。

In [34]: df2.reset_index()
Out[34]: 
  stock same1 same2  positions
0     A    AA   AAA        300 
1     B    BB   BBB        300 
2     C    CC   CCC        900

编辑

看起来我的方法不是很好。

感谢 @Andy 和 @unutbu,您可以通过更优雅的方式实现目标:

方法 1:

df.groupby(['stock', 'same1', 'same2'])['positions'].sum().reset_index()

方法二:

df.groupby(['stock', 'same1', 'same2'], as_index=False)['positions'].sum()

很好,所以第一步可以忽略。 - waitingkuo
2
如果您使用 df.groupby(['stock','same1','same2'], as_index=False),那么DataFrame将保留['stock','same1','same2']作为列(从而完全避免了reset_index())。 - unutbu
1
谢谢。很幸运能够通过回答这个问题学到很多东西。 - waitingkuo
只有一个问题。如果任何相同的列中有NaN,则该方法会中断。例如:same2 = pd.Series(['AAA','AAA',np.nan,np.nan,np.nan],name ='same2')在代码中替换它只是删除那些整行...认为这可能与pandas中的NaN ==问题有关? - Joop
1
已解决NaN的问题。由于这主要是不会在计算中使用的数据,因此在方法之前执行了df = df.fillna('')。 - Joop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接