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

AMa*_*Maz 10 python sum dataframe pandas

我是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
Run Code Online (Sandbox Code Playgroud)

我需要对数据进行累积求和,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. 
Run Code Online (Sandbox Code Playgroud)

在索引2 Num_Authors处达到条件.然后得到该索引:Num_Authors(2)=4

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

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

Nic*_*eli 7

选择 - 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
Run Code Online (Sandbox Code Playgroud)

当执行np.iscloseseries以后转换为一个数组:

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

选择 - 2:

pd.Index.get_loccumsum计算的系列上使用,该系列也支持tolerancenearest方法的参数.

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

选择 - 3:

使用idxmax找到的第一个指标True值后创建的布尔面具subabs操作上的cumsum系列:

df.get_value(df.Num_Albums.cumsum().sub(15).abs().le(2).idxmax(), 'Num_authors')
4
Run Code Online (Sandbox Code Playgroud)


Fab*_*nna 5

我认为你可以直接添加一列,其累积总和如下:

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
Run Code Online (Sandbox Code Playgroud)

然后在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
Run Code Online (Sandbox Code Playgroud)