【问题标题】:Working with few elements in a list belonging to a pandas dataframe使用属于 pandas 数据框的列表中的少数元素
【发布时间】:2020-11-12 00:09:31
【问题描述】:

考虑到我已经找到了解决问题的方法,但我想找到更好的方法和/或更多地了解熊猫数据框和应用/lambda 函数。 我有一个像这样的熊猫数据框:

                      A
0             [43,45,51,...,32]
1             [43,45,51,...,32]
2             [43,45,51,...,32]
...                  ...
...                  ...
...                  ...
n             [43,45,51,...,32]

A 列每行包含 64 个元素。 我想要的是对每一行应用一个函数:

  1. 仅对 A 列的某些元素求和(比如索引 18、27、34、45)
  2. 求总和的平均值
  3. 将平均值放入名为 B 的新列中

所以,最后我应该有这样的东西:

                      A                      B (mean over few elements)
0             [43,45,51,...,32]              50
1             [42,55,41,...,68]              60
2             [11,30,29,...,23]              30
...                  ...                    ...
...                  ...                    ...
...                  ...                    ...
n             [33,45,84,...,77]              70

现在我可以使用一个 numpy 数组来做到这一点,我在其中存储了 A 列,如下所示:

a = np.array(df["A"])
k =[18,27,34,45]
for i in range(n):
    vector = 0
    for idx, val in enumerate(k):
        vector = vector + a[i][val]
    mean.append(vector/16)

但我正在考虑使用 apply/lamdba 方法的更优雅的方法。如果不是创建另一列,而是将值附加到一个 numpy 列表,那也可以。 提前谢谢你和欢呼。

【问题讨论】:

    标签: python pandas dataframe lambda apply


    【解决方案1】:
    import pandas
    
    
    def column_generator(row_value, indices):
        # get a sublist of just the values that appear in the indices
        sublist = [row_value[index] for index in indices]
        # return average 
        return sum(sublist) / len(sublist)
    
    
    df['B'] = df['A'].apply(column_generator, indices=[0, 1])
    

    【讨论】:

      【解决方案2】:

      试试这个:

      indx = [0,2]
      func = [lambda x: np.mean([x[i] for i in indx])]
      df["mean"] = df.apply(func)
      

      【讨论】:

        【解决方案3】:

        A 列创建一个np.array,然后在索引为k 的数组中使用indexing 来选择所需的元素,并在axis=1 旁边使用np.mean 并将此结果分配回@ 列987654330@:

        a = np.array(df['A'].tolist())
        df['B'] = a[:, k].mean(axis=1)
        

        例子:

        np.random.seed(123)
        df = pd.DataFrame({'A': [np.random.randint(1, 10, 10) for _ in range(5)]})
        
        # print(df)
                                        A
        0  [3, 3, 7, 2, 4, 7, 2, 1, 2, 1]
        1  [1, 4, 5, 1, 1, 5, 2, 8, 4, 3]
        2  [5, 8, 3, 5, 9, 1, 8, 4, 5, 7]
        3  [2, 6, 7, 3, 2, 9, 4, 6, 1, 3]
        4  [7, 3, 5, 5, 7, 4, 1, 7, 5, 8]
        
        
        k =[1, 2, 4, 7]
        a = np.array(df['A'].tolist()) 
        df['B'] = a[:, k].mean(axis=1)
        

        结果:

                                        A     B
        0  [3, 3, 7, 2, 4, 7, 2, 1, 2, 1]  3.75
        1  [1, 4, 5, 1, 1, 5, 2, 8, 4, 3]  4.50
        2  [5, 8, 3, 5, 9, 1, 8, 4, 5, 7]  6.00
        3  [2, 6, 7, 3, 2, 9, 4, 6, 1, 3]  5.25
        4  [7, 3, 5, 5, 7, 4, 1, 7, 5, 8]  5.50
        

        【讨论】:

        • 不错 - 比我的回答好得多
        • 谢谢@Manakin :)。您在答案中实现的逻辑很好。但是使用explode 比较慢。
        • 是的,这是我在 pandas 中爆炸的唯一问题,它非常慢,几乎可以与 apply 媲美
        猜你喜欢
        • 2021-09-14
        • 2013-09-04
        • 1970-01-01
        • 2022-01-25
        • 2021-11-10
        • 2021-11-30
        • 2020-09-30
        • 2020-04-28
        • 1970-01-01
        相关资源
        最近更新 更多