我有一个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))
这需要我几个小时(????)。我希望有一些更快的方法,有人有什么想法吗?
谢谢
答案 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)