假設我有以下資料框:
values
0 4
1 0
2 2
3 3
4 0
5 8
6 5
7 1
8 0
9 4
10 7
我想找到一個熊貓矢量化函式(最好使用 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
有沒有實作這一目標的好方法?
uj5u.com熱心網友回復:
制作一個布爾掩碼以選擇具有零的行及其下一行,然后使用此布爾掩碼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
uj5u.com熱心網友回復:
以下功能應該為您完成這項作業。檢查函式中的注釋以了解解決方案的作業流程。
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
uj5u.com熱心網友回復:
獲取零的行,以及緊隨其后的行:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/463177.html
