Python数据框:达到条件之前的列的累积和并返回索引

时间:2017-01-05 15:25:58

标签: python pandas dataframe sum

我是Python的新手,我目前面临一个我无法解决的问题。我真的希望你能帮助我。英语不是我的母语,所以如果我不能正确表达自己,我很抱歉。

假设我有一个包含两列的简单数据框:

index  Num_Albums  Num_authors
0      10          4
1      1           5
2      4           4
3      7           1000
4      1           44
5      3           8

Num_Abums_tot = sum(Num_Albums) = 30

我需要在Num_Albums中对数据进行累积求和,直到达到某个条件。注册达到条件的索引,并从Num_authors获得相应的值。

实施例: 累计和Num_Albums直到总和等于50%±1/15( - > 15±2):

10 = 15±2? No, then continue;
10+1 =15±2? No, then continue
10+1+41 = 15±2? Yes, stop. 

在索引2处达到条件。然后在该索引处获得Num_AuthorsNum_Authors(2)=4

在我开始考虑如何使用while / for循环之前,我想看看pandas中是否已经实现了一个函数....

[我想指定我想要从相关索引中检索值的列(当我有4列时我会派上用场,我希望在第1列中对元素求和,条件达到=是然后得到第2栏中的对应值;然后对第3栏和第4栏进行相同的操作。

3 个答案:

答案 0 :(得分:6)

选项 - 1:

您可以使用cumsum计算累积总和。然后使用np.isclose及其内置容差参数来检查此系列中存在的值是否位于指定的15 +/- 2阈值内。这将返回一个布尔数组。

通过np.flatnonzero,返回True条件所适用的索引的序数值。我们选择True值的第一个实例。

最后,使用.iloc根据之前计算的索引检索所需列名的值。

val = np.flatnonzero(np.isclose(df.Num_Albums.cumsum().values, 15, atol=2))[0]
df['Num_authors'].iloc[val]      # for faster access, use .iat 
4

np.isclose上执行series后转换为数组:

np.isclose(df.Num_Albums.cumsum().values, 15, atol=2)
array([False, False,  True, False, False, False], dtype=bool)

选项 - 2:

cumsum计算的系列中使用pd.Index.get_loc,该系列也支持tolerance方法上的nearest参数。

val = pd.Index(df.Num_Albums.cumsum()).get_loc(15, 'nearest', tolerance=2)
df.get_value(val, 'Num_authors')
4

选项3:

使用idxmax查找在True系列subabs操作之后创建的布尔掩码的cumsum值的第一个索引:< / p>

df.get_value(df.Num_Albums.cumsum().sub(15).abs().le(2).idxmax(), 'Num_authors')
4

答案 1 :(得分:2)

我认为您可以直接添加累积和的列:

In [3]: df
Out[3]: 
   index  Num_Albums  Num_authors
0      0          10            4
1      1           1            5
2      2           4            4
3      3           7         1000
4      4           1           44
5      5           3            8

In [4]: df['cumsum'] = df['Num_Albums'].cumsum()

In [5]: df
Out[5]: 
   index  Num_Albums  Num_authors  cumsum
0      0          10            4      10
1      1           1            5      11
2      2           4            4      15
3      3           7         1000      22
4      4           1           44      23
5      5           3            8      26

然后在cumsum列上应用您想要的条件。例如,您可以使用where根据过滤器获取完整行。设置公差tol

In [18]: tol = 2

In [19]: cond = df.where((df['cumsum']>=15-tol)&(df['cumsum']<=15+tol)).dropna()

In [20]: cond
Out[20]: 
   index  Num_Albums  Num_authors  cumsum
2    2.0         4.0          4.0    15.0

答案 2 :(得分:1)

这甚至可以按照以下代码完成:

def your_function(df):
     sum=0
     index=-1
     for i in df['Num_Albums'].tolist():
       sum+=i
       index+=1
       if sum == ( " your_condition " ):
              return (index,df.loc([df.Num_Albums==i,'Num_authors']))

这实际上会在&#34;您的条件&#34;之后立即返回索引的元组和Num_authors的相应值。到了。

或者甚至可以通过

返回数组
def your_function(df):
     sum=0
     index=-1
     for i in df['Num_Albums'].tolist():
       sum+=i
       index+=1
       if sum == ( " your_condition " ):
              return df.loc([df.Num_Albums==i,'Num_authors']).index.values

我无法弄清楚你提到的累积金额的条件是什么时候停止求和所以我把它称为&#34; your_condition&#34;在代码!!

我也是新人,所以希望它有所帮助!!