一种使用fliplr 翻转零值位置的numpy 方法:
import numpy as np
import pandas as pd
df = pd.DataFrame({
'a1': {'row1': 1, 'row2': 0, 'row3': 0, 'row4': 0},
'a2': {'row1': 5, 'row2': 4, 'row3': 0, 'row4': 0},
'a3': {'row1': 5, 'row2': 1, 'row3': 7, 'row4': 0},
'a4': {'row1': 3, 'row2': 4, 'row3': 6, 'row4': 2}
})
mask = df.ne(0)
flipped = np.fliplr(mask)
df.values[flipped] = df.values[mask]
df.values[~flipped] = 0
df:
a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
一个类似的方法,除了将所有的 0 移动到末尾而不是仅仅翻转:
mask = df.ne(0).values
sorted_mask = np.take_along_axis(mask, np.argsort(~mask), axis=1)
df.values[sorted_mask] = df.values[mask]
df.values[~sorted_mask] = 0
修改df:
a1 a2 a3 a4
row1 1 0 5 3 # 0 added to a2
row2 0 4 1 4
row3 0 0 7 6
row4 0 0 0 2
翻转方法:
a1 a2 a3 a4
row1 1 5 0 3 # 0 position has been flipped
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
排序方法:
a1 a2 a3 a4
row1 1 5 3 0 # 0 is at end
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
翻转方法的分解:
mask = df.ne(0)
mask 保存非零值的位置:
a1 a2 a3 a4
row1 True True True True
row2 False True True True
row3 False False True True
row4 False False False True
flipped 持有掩码,0 翻转到另一侧:
[[ True True True True]
[ True True True False]
[ True True False False]
[ True False False False]]
df 中的非零值根据翻转被分配回:
df.values[flipped] # [1 5 5 3 0 4 1 0 0 0]
df.values[mask] # [1 5 5 3 4 1 4 7 6 2]
df.values[flipped] = df.values[mask]
a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 4
row3 7 6 7 6
row4 2 0 0 2
那么旧值需要用零覆盖:
df.values[~flipped] = 0
a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
排序方法类似,但不是翻转 mask 而是排序:
mask = df.ne(0).values
sorted_mask = np.take_along_axis(mask, np.argsort(~mask), axis=1)
df:
a1 a2 a3 a4
row1 1 0 5 3
row2 0 4 1 4
row3 0 0 7 6
row4 0 0 0 2
mask:
[[ True False True True]
[False True True True]
[False False True True]
[False False False True]]
sorted_mask:
[[ True True True False] # Falses are at end of the row always
[ True True True False]
[ True True False False]
[ True False False False]]