将数据帧中的每个值更改为原始值的更快方法

时间:2019-05-04 05:16:14

标签: pandas

我有一个30000列和4000行的数据框。每个单元格条目均包含一个整数。对于每个条目,我想将原始内容乘以log(k / m),

其中k是总行数,即4000 m是该特殊列的非零行总数。

我当前的代码使用apply

for column in df.columns:
    m = len(df[column].to_numpy().nonzero())
    df[column] = df[column].apply(lambda x: x * np.log10(4000/m))

这需要我几个小时(????)。我希望有一些更快的方法,有人有什么想法吗?

谢谢

2 个答案:

答案 0 :(得分:0)

首先生成样本数据:

resp.sendRedirect()

接下来,我定义一个包含非零列数的向量:

np.random.seed(123)

df = pd.DataFrame(np.random.rand(4, 5)*500, columns=['A', 'B', 'C', 'D', 'E']).astype(int).replace(range(100, 200), 0)

Result:

    A   B   C   D   E
0   348 0   0   275 359
1   211 490 342 240 0
2   0   364 219 29  0
3   368 91  87  265 265

从那里我找到每一列的对数因子:

non_zeros = df.ne(0).sum().values

# Giving me: array([3, 3, 3, 4, 2], dtype=int64)

然后将每列与其因子相乘,然后转换回DataFrame:

faktor = np.mat(np.log10(len(df)/ non_zeros))

# giving me: matrix([[0.12493874, 0.12493874, 0.12493874, 0.        , 0.30103   ]])

使用此解决方案,您可以解决Python中的非紧密循环。

希望它会带来一些帮助。

答案 1 :(得分:0)

@Dennis Hansen 的答案很好,但是如果您仍然需要遍历列,我建议您不要在您的列中使用apply解。

a = pd.DataFrame(np.random.rand(10000)) # define an arib. dataframe
a.iloc[5:500] = 0 # set some values to zero

具有应用性能的解决方案:

>> %%timeit
>> b = a.apply(lambda x: x * np.log10(10000/len(a.to_numpy().nonzero())))
1.53 ms ± 3.44 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

没有应用性能的解决方案:

>> %%timeit
>> b = a*np.log10(10000/len(a.to_numpy().nonzero()))
849 µs ± 3.74 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)