Pandas:值大于0的新列,并使用这些值进行操作



我有一个超过2500列的大数据帧,但结构与此非常相似:

A     B     C     D      E
0     1     0     8     0      0
1     0     0     0     0      5
2     1     2     3     0      0
3     0     2     0     1      0

我需要检测所有值大于0的列,我已经完成了以下操作:

df['X'] = df.gt(0).dot(df.columns + ',')

然后我得到了这个:

A     B     C     D      E    X
0     1     0     8     0      0    A,C
1     0     0     0     0      5    E
2     1     2     9     0      0    A,B,C
3     0     3     0     1      0    B,D

问题是,我不需要在"X"中输入列的名称,而是列的值,我需要执行以下数学运算:

我希望它只检测2个最低值,并从第二个最低值中减去最低值。在"X"中的值不超过2的情况下,我只显示列的值就足够了。

在我的示例中,最终结果如下:

A     B     C     D      E    X
0     1     0     8     0      0    7
1     0     0     0     0      5    5
2     1     2     9     0      0    1
3     0     3     0     1      0    2

知道如何解决它吗?或者有什么方向吗?

您可以将apply与函数一起使用,并且必须指定axis=1才能逐行应用该函数。我添加了一个get_diff函数,但没有100%,如果这正是您所需要的。我还添加了一个assign调用,以创建一个具有新列名X的新数据帧,其中包含所需的值

def get_diff(in_:pd.Series) -> int | float:
res = in_[in_ != 0].sort_values(ascending=False)
if len(res) == 0:
return 0 # Not sure if this is what you want to do in that case
return res[-2] - res[-1] if len(res) > 1 else res[0]
df = df.assign(X=lambda df: df.apply(get_diff, axis=1))

我们可以执行nsmallest,然后执行np.ptp,并且这些行的条件只有一个值不等于0

df['new'] = df.apply(lambda x :  np.ptp(pd.Series.nsmallest(x[x!=0],2)) if sum(x!=0) != 1 else x[x!=0].iloc[0],axis=1)
Out[520]: 
0    7
1    5
2    1
3    1
dtype: int64

或者做两步

df['new'] = df[df.ne(0).sum(1)>1].apply(lambda x :  np.ptp(pd.Series.nsmallest(x,2)),axis=1)
df['new'].fillna(df.max(1),inplace=True)
df
Out[530]: 
A  B  C  D  E  new
0  1  0  8  0  0  7.0
1  0  0  0  0  5  5.0
2  1  2  3  0  0  1.0
3  0  2  0  1  0  1.0

我认为您可以简单地使用apply(),因为您希望对每一行执行行操作。

请参阅https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.apply.html

一个选项是在排序和修剪以获得X:的值之前识别大于0的值

temp = df.where(df.gt(0), np.nan, axis = 0)
# you could use `np.partition` instead
# which should be more efficient
temp = np.sort(temp, axis = 1)[:, :2]
temp = np.nan_to_num(temp)
temp = np.ptp(temp, axis = 1)
df.assign(X = temp)
A  B  C  D  E    X
0  1  0  8  0  0  7.0
1  0  0  0  0  5  5.0
2  1  2  3  0  0  1.0
3  0  2  0  1  0  1.0

相关内容

最新更新