如何找到连续减少(增加)的数量

时间:2019-05-31 14:32:22

标签: python pandas numpy dataframe

如何找到连续减少(增加)的数量

我有一个数据框,其中包含500K行和12列(用于月份),包括开始和结束月份。每列代表一个月。我需要比较范围(startMonth,endmonth)中的第i个月和第(i + 1)个月的每一行。 (注:范围不是恒定的。每行的范围大小都不同。)

条件:如果开始月>结束月,我应该看到“ Neg99 = -999”

这是我的示例数据:

import pandas as pd
import numpy as np

idx = [1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013]
data = {'M_1': [3, 1, 0, 0, 1, 0, 1, 1, 1, 0, 6, 6, 6],
        'M_2': [2, 2, 3, 1, 1, 0, 1, 2, 0, 1, 5, 5, 5],
        'M_3': [1, 3, 2, 2, 1, 0, 1, 2, 1, 0, 4, 4, 4],
        'M_4': [0, 4, 1, 3, 1, 0, 1, 2, 0, 1, 3, 0, 3],
        'M_5': [1, 0, 0, 4, 2, 0, 1, 3, 1, 0, 2, 1, 2],
        'M_6': [2, 0, 0, 0, 3, 0, 1, 3, 0, 1, 1, 2, 1],
        'M_7': [3, 0, 0, 0, 2, 0, 1, 2, 1, 0, 0, 3, 0],
        'M_8': [0, 1, 0, 0, 2, 0, 1, 2, 0, 1, 1, 1, 1],
        'M_9': [0, 2, 0, 0, 1, 0, 1, 2, 1, 0, 0, 0, 0],
        'M_10': [0, 3, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0],
        'M_11': [0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
        'M_12': [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]}

startMonth = pd.DataFrame([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 5],
                          columns=['start'],index=idx)
endMonth = pd.DataFrame([12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2],
                        columns=['end'], index=idx)

df1 = pd.DataFrame(data, index=idx)
Neg99 = -999

我写了日期范围的布尔数组;

arr_bool = (np.less_equal.outer(startMonth.start, range(1,13)) 
            & np.greater_equal.outer(endMonth.end, range(1,13))
            )

masked=df1.filter(regex='M_[0-9]').mask(~arr_bool)

我需要找到每行的连续减少和增加。

  • 这是减少代码;
# Consecutive Decreases
decr = (np.diff(np.hstack((masked.values, np.zeros((masked.values.shape[0], 1)))), axis=1) > 0).argmin(axis=1)

final_decr = pd.DataFrame(decr,
                      index=idx, columns=['decr'])


final_decr.decr= np.select( condlist = [startMonth.start > endMonth.end],
                           choicelist = [Neg99],
                           default = final_decr.decr)
  • 这里是增加代码;
incr = (np.diff(np.hstack((masked.values, np.zeros((masked.values.shape[0], 1)))), axis=1) < 0).argmin(axis=1)

final_incr = pd.DataFrame(incr,
                      index=idx, columns=['incr'])
final_incr.incr= np.select( condlist = [startMonth.start > endMonth.end],
                           choicelist = [Neg99],
                           default = final_incr.incr)

最后,我的预期输出是;

expected_decr = [0,3,1,4,0,0,0,1,0,1,3,0,-999]
expected_decr = pd.DataFrame(expected_decr,index=idx)
expected_incr = [3,0,0,0,0,0,0,0,1,0,0,3,-999]
expected_incr = pd.DataFrame(expected_incr,index=idx)

感谢您的建议!

Final decrease table (.csv);
idx,my_results,expected_result
1001,0,0
1002,3,3
1003,1,1
1004,4,4
1005,0,0
1006,0,0
1007,0,0
1008,1,1
1009,0,0
1010,1,1
1011,0,3
1012,0,0
1013,-999,-999

Final increase table (.csv);
idx,my_result,expected_result
1001,3,3
1002,0,0
1003,0,0
1004,0,0
1005,0,0
1006,0,0
1007,0,0
1008,0,0
1009,1,1
1010,0,0
1011,0,0
1012,0,3
1013,-999,-999

1 个答案:

答案 0 :(得分:0)

因此,我认为可以在重命名列以获得位置的整数值之后使用idxmin来代替argmin。然后删除startMonth的值,例如:

incr = (df1.rename(columns={col:int(col.split('_')[1]) for col in masked.columns})
           .diff(-1, axis=1) < 0).mask(~arr_bool).idxmin(axis=1) - startMonth.start
decr = (df1.rename(columns={col:int(col.split('_')[1]) for col in masked.columns})
           .diff(-1, axis=1) > 0).mask(~arr_bool).idxmin(axis=1) - startMonth.start

然后,您可以像执行操作那样执行np.select,或者仅凭一个.illna(-999)就足够了,因为我认为,使用此解决方案,无论您遇到的情况如何,{{1 }}被满足