计算行中两个数字之间的 nans 数

Count number of nans between two numbers in row

我有一个 Pandas DataFrame,其中包含几天的消耗测量值,因此给定日期的测量值代表前几天没有测量值的消耗量。对于每个消费者(一行),我有类似

Nan, 10, Nan, Nan, Nan, Nan, Nan, Nan, 21, Nan, ...

意味着 1020 之间的平均消耗是 21/7=3,即 21 除以(6 个 NaN 加 1)。

测量值的间隔不规律,因此我需要将每个测量值除以它与前一个测量值之间的 NaN 数。我希望上面示例的输出为 Nan, 0.4347, Nan, Nan, Nan, Nan, Nan, Nan, 3, Nan, ...。第一次测量应该除以 23,但我可以不正确地生活。我怎样才能做到这一点?这是我的数据示例:

SP ID,2016-12-28,2016-12-29,2016-12-30,2016-12-31,2017-01-01,2017-01-03,2017-01-04,2017-01-05,2017-01-06,2017-01-09,2017-01-10,2017-01-11,2017-01-12,2017-01-13,2017-01-16,2017-01-17,2017-01-18,2017-01-19,2017-01-20,2017-01-21,2017-01-23,2017-01-24,2017-01-25,2017-01-26,2017-01-27,2017-01-29,2017-01-30,2017-01-31,2017-02-01,2017-02-02,2017-02-03,2017-02-06,2017-02-07,2017-02-08,2017-02-09,2017-02-10,2017-02-13,2017-02-14,2017-02-15,2017-02-16,2017-02-17,2017-02-18,2017-02-21,2017-02-22,2017-02-23,2017-02-24,2017-02-27,2017-02-28,2017-03-01,2017-03-02
100854,,,4.0,,,,,,,,,,,,,,,,,,,,,,,,,4.0,,,,,,,,,,,,,,,,,,,,3.0,,
120355,,,9.0,,,,,,,,,,,,,,,,,,,,,,,,9.0,,,,,,,,,,,,,,,,,,,,,,,9.0
200357,,,,,,,,,,,18.0,,,,,,,,,,,,,,,,,,,,,,,,22.0,,,,,,,,,,,,,,,

预期输出低于(第一次出现除以 23)。例如,我们有 4.0/25=0.16.

SP ID,2016-12-28,2016-12-29,2016-12-30,2016-12-31,2017-01-01,2017-01-03,2017-01-04,2017-01-05,2017-01-06,2017-01-09,2017-01-10,2017-01-11,2017-01-12,2017-01-13,2017-01-16,2017-01-17,2017-01-18,2017-01-19,2017-01-20,2017-01-21,2017-01-23,2017-01-24,2017-01-25,2017-01-26,2017-01-27,2017-01-29,2017-01-30,2017-01-31,2017-02-01,2017-02-02,2017-02-03,2017-02-06,2017-02-07,2017-02-08,2017-02-09,2017-02-10,2017-02-13,2017-02-14,2017-02-15,2017-02-16,2017-02-17,2017-02-18,2017-02-21,2017-02-22,2017-02-23,2017-02-24,2017-02-27,2017-02-28,2017-03-01,2017-03-02
100854,,,0.17,,,,,,,,,,,,,,,,,,,,,,,,,0.16,,,,,,,,,,,,,,,,,,,,0.15,,
120355,,,0.391,,,,,,,,,,,,,,,,,,,,,,,,0.375,,,,,,,,,,,,,,,,,,,,,,,0.391
200357,,,,,,,,,,,0.78,,,,,,,,,,,,,,,,,,,,,,,,0.917,,,,,,,,,,,,,,

使用 applyaxis=1 在每一行上应用自定义函数。在函数内部,您可以找到非空索引和每个连续对之间的差异。对于第一个差异,我们可以根据需要将其硬编码为 23。

def row_norm(row):
    indices = row.reset_index(drop=True)
    indices = indices[indices.notna()].index.values
    diffs = [e-s for s, e in zip(indices, indices[1:])]
    
    diffs[0] = 23
    row.iloc[indices[1:]] = row.iloc[indices[1:]].astype(float) / diffs
    return row

df.apply(row_norm, axis=1)

结果:

SP ID  2016-12-28  2016-12-29  2016-12-30  2016-12-31  2017-01-01  2017-01-03  2017-01-04  2017-01-05  2017-01-06  2017-01-09  2017-01-10  2017-01-11  2017-01-12  2017-01-13  2017-01-16  2017-01-17  2017-01-18  2017-01-19  2017-01-20  2017-01-21  2017-01-23  2017-01-24  2017-01-25  2017-01-26  2017-01-27  2017-01-29  2017-01-30  2017-01-31  2017-02-01  2017-02-02  2017-02-03  2017-02-06  2017-02-07  2017-02-08  2017-02-09  2017-02-10  2017-02-13  2017-02-14  2017-02-15  2017-02-16  2017-02-17  2017-02-18  2017-02-21  2017-02-22  2017-02-23  2017-02-24  2017-02-27  2017-02-28  2017-03-01  2017-03-02
0  100854.0         NaN         NaN    0.173913         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN        0.16         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN        0.15         NaN         NaN
1  120355.0         NaN         NaN    0.391304         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN       0.375         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN    0.391304
2  200357.0         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN    0.782609         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN    0.916667         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN         NaN