Pandas:对于DataFrame中的每一行,计算与条件匹配的行数

时间:2017-06-10 00:47:37

标签: python pandas dataframe

我想要为每行计算一个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])

有没有办法对此进行矢量化?

谢谢!

2 个答案:

答案 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