我想要为每行计算一个DataFrame,其中有多少其他行与给定条件匹配(例如,列C中的值小于此行值的行数)。迭代每一行太慢(我有~1B行),特别是当列dtype是一个日期时间时,但这是它可以在一个带有标记为C的列的DataFrame df上运行的方式:
df['newcol'] = 0
for row in df.itertuples():
df.loc[row.Index, 'newcol'] = len(df[df.C < row.C])
有没有办法对此进行矢量化?
谢谢!
答案 0 :(得分:2)
的制备:将
import numpy as np
import pandas as pd
count = 5000
np.random.seed(100)
data = np.random.randint(100, size=count)
df = pd.DataFrame({'Col': list('ABCDE') * (count/5),
'Val': data})
<强>建议:强>
u, c = np.unique(data, return_counts=True)
values = np.cumsum(c)
dictionary = dict(zip(u[1:], values[:-1]))
dictionary[u[0]] = 0
df['newcol'] = [dictionary[x] for x in data]
它与您的示例完全相同。 如果它没有帮助。写下更详细的问题。
<强>建议:强>
在page numba 可以使用Pandas矢量化和jit编译。
如果使用1d数组 - 请使用numpy。在许多情况下,它工作得更快。只需比较一下:
<强>熊猫强>
%timeit df['newcol2'] = df.apply(lambda x: sum(df['Val'] < x.Val), axis=1)
1循环,最佳3:每循环51.1秒 204.34800005 强>
<强> numpy的强>
%timeit df['newcol3'] = [np.sum(data<x) for x in data]
10个循环,最好3个循环:每个循环61.3毫秒 2.5490000248 强>
使用numpy.sum而不是sum!
答案 1 :(得分:0)
考虑使用lambda表达式的pandas.DataFrame.apply来计算符合条件的行。不可否认,apply
是一个循环,运行大约10亿行可能需要一段时间来处理。
import numpy as np
import pandas as pd
np.random.seed(161)
df = pd.DataFrame({'Col': list('ABCDE') * 3,
'Val': np.random.randint(100, size=15)})
df['newcol'] = df.apply(lambda x: sum(df['Val'] < x.Val), axis=1)
# Col Val Count
# 0 A 78 13
# 1 B 11 2
# 2 C 51 8
# 3 D 31 5
# 4 E 29 4
# 5 A 99 14
# 6 B 65 10
# 7 C 16 3
# 8 D 43 7
# 9 E 10 1
# 10 A 67 11
# 11 B 36 6
# 12 C 1 0
# 13 D 73 12
# 14 E 64 9