<p>使用<a href="https://numpy.org/doc/stable/reference/generated/numpy.fliplr.html#numpy.fliplr" rel="nofollow noreferrer">^{<cd1>}</a>翻转零值位置的numpy方法:</p>
<pre><code>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
</code></pre>
<p><code>df</code>:</p>
<pre><code> a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
</code></pre>
<hr/>
<p>类似的方法除了将所有0移动到末尾,而不仅仅是翻转:</p>
<pre><code>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
</code></pre>
<p>修改的<code>df</code>:</p>
<pre><code> 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
</code></pre>
<p>翻转方法:</p>
<pre><code> 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
</code></pre>
<p>排序方法:</p>
<pre><code> 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
</code></pre>
<hr/>
<p>翻转方法的细分:</p>
<pre><code>mask = df.ne(0)
</code></pre>
<p><code>mask</code>保存非零值的位置:</p>
<pre><code> a1 a2 a3 a4
row1 True True True True
row2 False True True True
row3 False False True True
row4 False False False True
</code></pre>
<p><code>flipped</code>将0翻转到另一侧以保持掩码:</p>
<pre><code>[[ True True True True]
[ True True True False]
[ True True False False]
[ True False False False]]
</code></pre>
<p>来自<code>df</code>的非零值将根据翻转的:</p>
<pre><code>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]
</code></pre>
<pre><code>df.values[flipped] = df.values[mask]
</code></pre>
<pre><code> a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 4
row3 7 6 7 6
row4 2 0 0 2
</code></pre>
<p>然后旧值需要用零覆盖:</p>
<pre><code>df.values[~flipped] = 0
</code></pre>
<pre><code> a1 a2 a3 a4
row1 1 5 5 3
row2 4 1 4 0
row3 7 6 0 0
row4 2 0 0 0
</code></pre>
<hr/>
<p>排序方法类似,但不是翻转<code>mask</code>而是进行排序:</p>
<pre><code>mask = df.ne(0).values
sorted_mask = np.take_along_axis(mask, np.argsort(~mask), axis=1)
</code></pre>
<p><code>df</code>:</p>
<pre><code> a1 a2 a3 a4
row1 1 0 5 3
row2 0 4 1 4
row3 0 0 7 6
row4 0 0 0 2
</code></pre>
<p><code>mask</code>:</p>
<pre><code>[[ True False True True]
[False True True True]
[False False True True]
[False False False True]]
</code></pre>
<p><code>sorted_mask</code>:</p>
<pre><code>[[ True True True False] # Falses are at end of the row always
[ True True True False]
[ True True False False]
[ True False False False]]
</code></pre>