【问题标题】:Row sums of dataframe with variable column indexes (Python)具有可变列索引的数据帧的行总和(Python)
【发布时间】:2022-01-05 20:14:33
【问题描述】:

我有一个包含几百万行的数据框。我需要计算从特定列索引到最后一列的每一行的总和。每行的列索引是唯一的。具有所需输出的示例如下:

import pandas as pd

df = pd.DataFrame({'col1': [1, 2, 2, 5, None, 4],
                   'col2': [4, 2, 4, 2, None, 1],
                   'col3': [6, 3, 8, 6, None, 4],
                   'col4': [9, 8, 9, 3, None, 5],
                   'col5': [1, 3, 0, 1, None, 7],
                   })

df_ind = pd.DataFrame({'ind': [1, 0, 3, 4, 3, 5]})

for i in df.index.to_list():
    df.loc[i, "total"] = df.loc[i][(df_ind.loc[i, "ind"]).astype(int):].sum()

print(df)

>>
   col1  col2  col3  col4  col5  total
0   1.0   4.0   6.0   9.0   1.0   20.0
1   2.0   2.0   3.0   8.0   3.0   18.0
2   2.0   4.0   8.0   9.0   0.0    9.0
3   5.0   2.0   6.0   3.0   1.0    1.0
4   NaN   NaN   NaN   NaN   NaN    0.0
5   4.0   1.0   4.0   5.0   7.0    0.0

如何在不使用 for 循环的情况下使用 pandas 有效地实现这一点。谢谢

【问题讨论】:

    标签: python pandas sum row


    【解决方案1】:

    您可以创建一个列出所有列位置的类似索引数据帧,然后通过将此数据帧与df_ind 进行比较,您可以为整个原始数据帧创建一个掩码。

    然后mask 原始DataFrame 和sum 根据行不同的适当索引位置获取行总和。

    import pandas as pd
    
    mask = pd.DataFrame({col: df.columns.get_loc(col) for col in df.columns}, 
                        index=df.index)
    #   col1  col2  col3  col4  col5
    #0     0     1     2     3     4
    #1     0     1     2     3     4
    #2     0     1     2     3     4
    #3     0     1     2     3     4
    #4     0     1     2     3     4
    #5     0     1     2     3     4
    
    mask = mask.ge(df_ind['ind'], axis=0)
    #    col1   col2   col3   col4   col5
    #0  False   True   True   True   True
    #1   True   True   True   True   True
    #2  False  False  False   True   True
    #3  False  False  False  False   True
    #4  False  False  False   True   True
    #5  False  False  False  False  False
    
    df['total'] = df[mask].sum(1)
    

    print(df)
       col1  col2  col3  col4  col5  total
    0   1.0   4.0   6.0   9.0   1.0   20.0
    1   2.0   2.0   3.0   8.0   3.0   18.0
    2   2.0   4.0   8.0   9.0   0.0    9.0
    3   5.0   2.0   6.0   3.0   1.0    1.0
    4   NaN   NaN   NaN   NaN   NaN    0.0
    5   4.0   1.0   4.0   5.0   7.0    0.0
    

    【讨论】:

      【解决方案2】:

      另一种选择,使用 numpy:

      
      cols = np.arange(len(df.columns))
      # build a 2D array
      mask = np.tile(cols, (len(df), 1))
      # generate booleans by comparing to `df_ind`
      mask = mask >= df_ind.to_numpy()
      # replace True with `df`
      mask = np.where(mask, df, mask)
      # convert nulls to zero, and sum along the columns
      mask = np.nan_to_num(mask).sum(1)
      df.assign(total = mask)
      
         col1  col2  col3  col4  col5  total
      0   1.0   4.0   6.0   9.0   1.0   20.0
      1   2.0   2.0   3.0   8.0   3.0   18.0
      2   2.0   4.0   8.0   9.0   0.0    9.0
      3   5.0   2.0   6.0   3.0   1.0    1.0
      4   NaN   NaN   NaN   NaN   NaN    0.0
      5   4.0   1.0   4.0   5.0   7.0    0.0
      

      【讨论】:

        猜你喜欢
        • 2017-02-06
        • 2019-05-07
        • 2019-08-12
        • 1970-01-01
        • 2019-01-03
        • 2021-11-29
        • 2018-02-08
        • 1970-01-01
        • 2020-08-03
        相关资源
        最近更新 更多