每个零值后Pandas的常数值。

5

假设我有以下数据框:

    values
0      4
1      0
2      2
3      3
4      0
5      8
6      5
7      1
8      0
9      4
10     7

我希望找到一个基于Pandas的向量化函数(最好使用groupby),它可以将所有非零值替换为该非零值块中的第一个非零值,即返回以下结果:
    values   new
0      4      4
1      0      0
2      2      2
3      3      2
4      0      0
5      8      8
6      5      8
7      1      8
8      0      0
9      4      4
10     7      4

有没有一个好的方法来实现这个?


因为回顾行时,您可能需要考虑使用.apply()作为向量化方法。这里是否可以使用groupby() - D.L
3个回答

4

创建一个布尔屏蔽器以选择具有零及其以下行的行,然后使用此布尔屏蔽器与where一起替换剩余值为NaN,之后向前填充以向前传播值。

m = df['values'].eq(0)
df['new'] = df['values'].where(m | m.shift()).ffill().fillna(df['values'])

结果

print(df)

    values  new
0        4  4.0
1        0  0.0
2        2  2.0
3        3  2.0
4        0  0.0
5        8  8.0
6        5  8.0
7        1  8.0
8        0  0.0
9        4  4.0
10       7  4.0

2
获取所有值为零的行以及紧随其后的行:
zeros = df.index[df['values'].eq(0)]
after_zeros = zeros.union(zeros +1)

获取需要进行向前填充的行:
replace = df.index.difference(after_zeros)
replace = replace[replace > zeros[0]]

replace上设置数值并向前填充:

df['new'] = df['values']
df.loc[replace, 'new'] = np.nan
df.ffill()


values  new
0   4   4.0
1   0   0.0
2   2   2.0
3   3   2.0
4   0   0.0
5   8   8.0
6   5   8.0
7   1   8.0
8   0   0.0
9   4   4.0
10  7   4.0

这也是一个不错的方法 :) - Shubham Sharma

1
以下函数可以帮助您完成任务。请查看函数中的注释,了解解决方案的工作流程。
import pandas as pd

def ffill_nonZeros(values):
    # get the values that are not equal to 0
    non_zero = values[df['values'] != 0]

    # get their indexes
    non_zero_idx = non_zero.index.to_series()

    # find where indexes are consecutive
    diff = non_zero_idx.diff()
    mask = diff == 1

    # using the mask make all places in non_zero where the change is consecutive equal None
    non_zero[mask] = None

    # fill forward (replace all None values with previous valid value)
    new_non_zero = non_zero.fillna(method='ffill')

    # put new values back in their indexs
    new = values.copy()
    new[new_non_zero.index] = new_non_zero

    return new

现在将此函数应用于您的数据:
df = pd.DataFrame([4, 0, 2, 3, 0, 8, 5, 1, 0, 4, 7], columns=['values'])
df['new'] = ffill_nonZeros(df['values'])
print(df)

输出:

    values  new
0        4    4
1        0    0
2        2    2
3        3    2
4        0    0
5        8    8
6        5    8
7        1    8
8        0    0
9        4    4
10       7    4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接