11

我有一个像这样的熊猫数据框:

    Balance       Jan       Feb       Mar       Apr
0  9.724135  0.389376  0.464451  0.229964  0.691504
1  1.114782  0.838406  0.679096  0.185135  0.143883
2  7.613946  0.960876  0.220274  0.788265  0.606402
3  0.144517  0.800086  0.287874  0.223539  0.206002
4  1.332838  0.430812  0.939402  0.045262  0.388466

我想通过确定从 Jan 到 Apr 的值是否单调递减(如索引 1 和 3 的行)对行进行分组,然后将每个组的余额相加,即最后我想最终得到两个数字(递减时间序列为 1.259299,其他数字为 18.670919)。

我想如果我可以添加一个“正在减少”的包含布尔值的列,我可以使用 pandas 的 groupby 来计算总和,但是我将如何创建这个列?

谢谢,安妮

4

4 回答 4

12

您可以使用算法中的is_monotonic功能之一:

In [10]: months = ['Jan', 'Feb', 'Mar', 'Apr']

In [11]: df.loc[:, months].apply(lambda x: pd.algos.is_monotonic_float64(-x)[0],
                                       axis=1)
Out[11]:
0    False
1     True
2    False
3     True
4    False
dtype: bool

is_monotonic检查数组是否在减少因此-x.values.

(这似乎比 Tom 的解决方案快得多,即使使用提供的小型 DataFrame 也是如此。)

于 2013-07-17T16:38:32.737 回答
7
months = ['Jan', 'Feb', 'Mar', 'Apr']

转置以便我们可以使用该diff方法(它不接受轴参数)。我们用 0 填充第一行(一月)。否则为NaN.

In [77]: df[months].T.diff().fillna(0) <= 0
Out[77]: 
         0     1      2     3      4
Jan   True  True   True  True   True
Feb  False  True   True  True  False
Mar   True  True  False  True   True
Apr  False  True   True  True  False

要检查它是否单调递减,请使用 .all() 方法。默认情况下,这会超过轴 0,即行(月)。

In [78]: is_decreasing = (df[months].T.diff().fillna(0) <= 0).all()

In [79]: is_decreasing
Out[79]: 
0    False
1     True
2    False
3     True
4    False
dtype: bool

In [80]: df['is_decreasing'] = is_decreasing

In [81]: df
Out[81]: 
    Balance       Jan       Feb       Mar       Apr is_decreasing
0  9.724135  0.389376  0.464451  0.229964  0.691504         False
1  1.114782  0.838406  0.679096  0.185135  0.143883          True
2  7.613946  0.960876  0.220274  0.788265  0.606402         False
3  0.144517  0.800086  0.287874  0.223539  0.206002          True
4  1.332838  0.430812  0.939402  0.045262  0.388466         False

就像你建议的那样,我们可以分组is_decreasing和求和:

In [83]: df.groupby('is_decreasing')['Balance'].sum()
Out[83]: 
is_decreasing
False            18.670919
True              1.259299
Name: Balance, dtype: float64

我喜欢熊猫的时候就是这样。

于 2013-07-17T16:08:44.713 回答
0
months = ['Jan', 'Feb', 'Mar', 'Apr']

df[df.loc[:, months].apply(lambda x: x.is_monotonic,axis=1)]

注意:pandas 声明这is_monotonic_increasing是一个别名,is_monotonic因此您可以使用其中任何一个

于 2021-02-08T21:55:38.607 回答
0

Pandas 0.19添加了一个Series.is_monotonic属性(如前所述,该algos模块已从 Pandas 公共 API 中删除)。

正如@Liam 在他的回答中指出的那样,is_monotonic实际上是 的别名is_monotonic_increasing,所以为了清楚起见,我建议直接使用is_monotonic_increasingor is_monotonic_decreasing

无论如何,两者都是非严格的(即当序列减少相等时is_monotonic_decreasing返回),但如果您需要严格性,您可以将它们结合起来。Trueis_unqiue

my_df = pd.DataFrame({'A':[1,2,3],'B':[1,1,1],'C':[3,2,1]})
my_df

Out[32]: 
   A  B  C
0  1  1  3
1  2  1  2
2  3  1  1

my_df.apply(lambda x: x.is_monotonic_increasing)  # row-wise monotonic (default axis is 0)

Out[33]: 
A     True
B     True
C    False
dtype: bool

my_df.apply(lambda x: x.is_monotonic_increasing, axis=1)  # column-wise monotonic

Out[34]: 
0     True
1    False
2    False
dtype: bool
于 2018-01-17T11:58:54.507 回答