在pandas

时间:2018-02-02 00:29:58

标签: python pandas

让我从一个最小的工作示例开始。

import pandas as pd
import numpy as np
import math
test = pd.DataFrame(data=np.array([[45, .25, .25, .25, .25], 
                                   [37, .75, .25, 0.0, 0.0], 
                                   [29, 1, 0.0, 0.0, 0.0], 
                                   [70, .25, 0.0, 0.0, .57]]), 
                    index=[1, 2, 3, 4], 
                    columns=['Unneeded', 'A', 'B', 'C', 'D'])

因此,我们在pandas中有以下数据框:

>>> test
   Unneeded     A     B     C     D
1      45.0  0.25  0.25  0.25  0.25
2      37.0  0.75  0.25  0.00  0.00
3      29.0  1.00  0.00  0.00  0.00
4      70.0  0.25  0.00  0.00  0.57

变量AD代表某些东西的份额,这就是为什么逐行添加一个。我想计算一个新变量,它保存每行的熵索引。熵指数是以下函数的x = A,B,C,D之和:

lambda x: x * math.log(1.0/x, 2) if x > 0 else 0

我知道我可以通过以下语法在pandas数据框中进行简单的列生成:

test['sum_ab'] = test['A'] + test['B']

我也知道我可以使用lambda函数生成具有更复杂转换的列:

test['dub_a'] = test.A.apply(lambda x: x * 2) # or test['A'].apply(...

我也知道你可以使用带有map()的lambda函数将函数应用于列表中的每个项目。所以我的想法是通过将必要的lambda函数应用于这四列中的每个项来生成一个新变量,然后对结果列表中的项求和。因此我尝试了以下语法:

test['entropy'] = sum(list(map(lambda x: x * math.log(1.0/x, 2) \
    if x > 0 else 0, LIST)))

......但是我的麻烦开始了。我刚刚在那里写了LIST,因为在我的生活中,我无法弄清楚如何从这些中找出一个列表列名,以便此函数可以工作。我知道基本思想本身有效:

>>> list_1 = [.25, .25, .25, .25]
>>> entropy_1 = sum(list(map(lambda x: x * math.log(1.0/x, 2) \
        if x > 0 else 0, list_1)))
>>> entropy_1
2.0

我无法弄清楚如何告诉它对pandas数据框中列的元素执行此操作。

到目前为止,我在大熊猫上阅读的所有内容,当涉及到选择列时,似乎都假设您正在对数据框进行子集化。但这不是我想要做的。这种类型的列创建隐式地同时对列中的每一行起作用;因此,当您编写test['sum_ab'] = test['A'] + test['B']之类的内容时,您不会指定任何(或所有)行。看起来我应该可以在这里执行类似的操作:我应该能够将test[['A':'D']]或类似内容指定为LIST。但到目前为止我还是来了鸡蛋。

通常当我接近一个解决方案然后找不到任何相关问题时,这表明我基本上是错误的轨道。这可能是这种情况,但如果有人对如何进行有任何想法,我将不胜感激。

P.S。:我包含了Unneeded列,以强调我需要指定数据框中的一些列,而不是所有列。

1 个答案:

答案 0 :(得分:3)

作为apply的替代方案,您可以使用矢量化操作。

relevant = test[['A','B','C','D']]
entropy = (relevant * (np.log2(1) - np.log2(relevant))).fillna(0).sum(1)

首先,计算一个框架,其中每个条目的格式为x * np.log2(1/x)0。然后,对各行求和以获得答案。