Pandas - 神经网络的快速DataFrame转换(“gausrank”)

时间:2017-12-03 08:47:18

标签: python pandas dataframe transformation ranking

首先,谢谢你的帮助

我有大型pandas DataFrame,我需要为每列快速“排名”转换:

1]如果列只有0-1,则什么都不做

2]其他(对于每一栏):

a]在列

中查找唯一值

b]对它们进行排序

c]对于列的每个元素,将其值替换为sort-unique“排名”列表中的位置

可选的:

d]将这个新值转换为区间[-0.99,0.99]

e]将scipy.special.erfinv应用于每个元素(以获得“正常”的分布)

如果需要关注速度,我怎么能和熊猫一起做这件事呢。

感谢名单

1 个答案:

答案 0 :(得分:4)

获取仅包含01

的列
columns_to_handle = (~df.isin([0,1])).any()

将列类型转换为分类可以方便地处理步骤a,b和c:

df.some_column.astype('category').cat.codes

不幸的是,这似乎需要在列上进行循环(通过apply),但如果您没有太多列,那么这仍然应该相当快。

重新缩放可以通过减去最小值并除以每列的最大值来完成。但是,由于每列的最小值已经为0,因此第一步是多余的。

Scipy的erfinv可以将数据帧作为输入。但是,值必须介于-11之间,独占。因此范围将epsilon更小。

全部合并

import pandas as pd
from scipy.special import erfinv

df = pd.DataFrame(
    [['a', 10, 0],
     ['b', 11, 1],
     ['c',  9, 0],
     ['d', 12, 1]],
    columns=['val1', 'val2', 'val3']
)

columns_to_handle = (~df.isin([0, 1])).any()

intermediate = df.loc[:, columns_to_handle].apply(lambda x: x.astype('category').cat.codes)

epsilon = 0.0001

# intermediate -= intermediate.min() # the minimum is 0 for every column already
intermediate /= intermediate.max()/(2-2*epsilon)
intermediate -= (1-epsilon)

intermediate = erfinv(intermediate)

result = pd.concat(
   [intermediate,
    df.loc[:, ~columns_to_handle]],
  axis=1)

result是以下数据框:

       val1      val2  val3
0 -2.751064 -0.304538     0
1 -0.304538  0.304538     1
2  0.304538 -2.751064     0
3  2.751064  2.751064     1