熊猫:如何将SUMIF与excel相似

时间:2020-10-16 22:53:55

标签: python excel

我有一个包含400,000个数据点的数据集,我需要执行SUMIF语句,我可以在excel中编写该函数,而不会崩溃一个小的子集,但是我希望能够对熊猫使用excel公式很简单:

=SUMIF(K$3:K$10000,"<"&K3,I$3:I$10000)/SUM(I$3:I$10000)*100

我编写了一个有效的代码,但是处理整个数据集的速度非常慢(约4小时)。我觉得有一个更快的方法。 excel函数最后与for循环对齐。

Python代码:

import pandas as pd
import numpy as np
                
#Initialize Variables
#Import file
df = pd.read_csv('export_dataframe.csv')
df['Rank'] = df['% Grain'].iloc[:].rank(ascending=0,method='max', na_option = 'bottom')
df['Mass'] = df['Rank'].iloc[:]/np.count_nonzero(df['Rank'].iloc[:])*100
Total_Cu = df['Cumulative Grain'].sum()
df['Cumulative Grain'] = 0
for i in range(len(df['Rank'])):
            df['Cumulative Grain'].iloc[i]=df.loc[df['Rank']<df['Rank'].iloc[i],'Cu % Grade'].sum()/df['Cu % Grade'].sum()*100

编辑: 我看了另一个问题的答案,它与之类似,但是它依赖于条件是恒定的,在我的情况下,列表中的每个项目都会基于该特定单元格中的值而具有不同的条件。可能只是我不知道如何正确使用lambda。这是我试图修复的方法,但是没有用。

df['Cummulative Cu'] = df.apply(lambda x: x['Cu % Grade'] if x['Rank'] < x['Rank'].iloc[:] else 0, axis=1)
df.matches.sum()

1 个答案:

答案 0 :(得分:0)

因此,我不确定“ export_dataframe.csv”中的内容,因此也不确定数据框中的列。我能够将您的for循环包装在列表理解中,而且我认为它可以满足您的需求,而且速度要快得多。您在循环中引用了df['Cu % Grade'],但是在您之前的代码中却没有看到它,因此,如果代码没有引用您需要的确切列,则感到抱歉。我敢肯定,您可以对其进行一些修改以适应需要。

import pandas as pd
import numpy as np
import timeit

# make a DF
df = pd.DataFrame({'Cu % Grade': np.linspace(0,1,10000)})
df['Rank'] = df['Cu % Grade'].rank(ascending=0,method='max', na_option = 'bottom')
df['Cummulative Cu'] = [(df.loc[df['Rank'] < df.loc[i, 'Rank'], 'Cu % Grade'].sum()/ df['Cu % Grade'].sum())*100 for i in range(len(df))]

因此,有了1万行,我得到...

s = '''
df['Cummulative Cu'] = [(df.loc[df['Rank'] < df.loc[i, 'Rank'], 'Cu % Grade'].sum()/ df['Cu % Grade'].sum())*100 for i in range(len(df))]
'''

%timeit s
14.7 ns ± 0.241 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

一个快速提示:如果您发现自己要使用for循环,通常可以更快地将其包装在列表理解中。您可以在此处了解列表的理解:list comprehensions in python