我有增长数据。我想通过删除低于此阈值的所有值并将所有列中的值“上移”,以将所有列校准为某个(任意)截止值。
说明:
import pandas as pd
df = pd.DataFrame([[1, 2], [3, 4],[5, 6]], columns=list('AB'))
结果:
A B
0 1 2
1 3 4
2 5 6
删除所有低于3的值:
df = df.where(df > 3, np.nan)
结果:
A B
0 NaN NaN
1 NaN 4
2 5 6
我最终想要的是以下数据框(在某种意义上,将大于3的值剪切并粘贴到df的顶部):
A B
0 5 4
1 NaN 6
2 NaN NaN
有什么想法可以做到吗?
答案 0 :(得分:1)
使用justify
函数来提高性能:
df = pd.DataFrame([[1, 2], [3, 4],[5, 6]], columns=list('AB'))
df = df.where(df > 3, np.nan)
arr = justify(df.to_numpy(), invalid_val=np.nan, axis=0, side='up')
#oldier pandas versions
arr = justify(df.values, invalid_val=np.nan, axis=0, side='up')
df = pd.DataFrame(arr, columns=df.columns)
print (df)
A B
0 5.0 4.0
1 NaN 6.0
2 NaN NaN
divakar的功能:
def justify(a, invalid_val=0, axis=1, side='left'):
"""
Justifies a 2D array
Parameters
----------
A : ndarray
Input array to be justified
axis : int
Axis along which justification is to be made
side : str
Direction of justification. It could be 'left', 'right', 'up', 'down'
It should be 'left' or 'right' for axis=1 and 'up' or 'down' for axis=0.
"""
if invalid_val is np.nan:
mask = ~np.isnan(a)
else:
mask = a!=invalid_val
justified_mask = np.sort(mask,axis=axis)
if (side=='up') | (side=='left'):
justified_mask = np.flip(justified_mask,axis=axis)
out = np.full(a.shape, invalid_val)
if axis==1:
out[justified_mask] = a[mask]
else:
out.T[justified_mask.T] = a.T[mask.T]
return out
答案 1 :(得分:1)
我将通过以下方式使用内置的Python node
来做到这一点:
sorted
输出:
import numpy as np
import pandas as pd
df = pd.DataFrame([[1, 2], [3, 6],[5, 4]], columns=list('AB'))
df = df.where(df > 3, np.nan)
print(df)
然后就做:
A B
0 NaN NaN
1 NaN 6.0
2 5.0 4.0
输出:
for col in df.columns:
df[col] = sorted(df[col], key=pd.isnull)
print(df)
我利用了内置 A B
0 5.0 6.0
1 NaN 4.0
2 NaN NaN
是稳定的事实(请注意,我稍微更改了输入(sorted
之前的6
来表明这一点)。 4
函数为所有非isnull
生成False
,在排序过程中将其生成为NaN
,而其余的0
则生成为True
在排序过程中。