涉及列中混合类型元素的计算-np.nan、float、字符串元素



我有一个数据框架,其中的列包括混合类型元素,我需要在它们之间进行一些计算。假设此数据帧:

A=[20, np.nan, 10, 'give', np.nan, np.nan]
B=[10, np.nan, np.nan, np.nan, 10, 'given']
frame=pd.DataFrame(zip(A,B))
frame.columns=['A', 'B']

我想填充B与A的差异。如果我做frame['diff']=frame['A']-frame['B'],它不会给出我需要的结果。相反,我想要的结果是在"所需的diff"列中。

基本上,如果A或B有一个数字,那么B或A应该是0。如果一个字符串在a中,而B是NaN,则它应该写"正",反之亦然,则应该写"负"。见下文:

frame
A      B  diff  desired diff
0    20     10    10            10
1   NaN    NaN   NaN           NaN
2    10    NaN   NaN            10
3  give    NaN   NaN      positive
4   NaN     10   NaN           -10
5   NaN  given   NaN      negative

为了记录在案,我曾尝试实现np.wherenp.select以及一些条件,如np.logical_and(frame['A'].apply(lambda x: isinstance(x, float)), frame['B'].isna()),以实现所需的输出,但没有成功。

提前感谢您的建议!

使用to_numericerrors='coerce'检查非数字值和无缺失值,并使用fill_value=0参数通过numpy.select设置新值,通过Series.sub减去值:

a = pd.to_numeric(frame['A'], errors='coerce')
m1 = frame['A'].notna()
m2 = a.isna()
b = pd.to_numeric(frame['B'], errors='coerce')
m3 = frame['B'].notna()
m4 = b.isna()
frame['new'] = np.select([m1 & m2, m3 & m4], 
['positive', 'negative'], 
default = a.sub(b, fill_value=0))
print (frame)
A      B       new
0    20     10      10.0
1   NaN    NaN       nan
2    10    NaN      10.0
3  give    NaN  positive
4   NaN     10     -10.0
5   NaN  given  negative

如果你想使用长应用程序,我不建议使用:

frame['diff'] = (frame.fillna(0)
.apply(lambda x: x.A-x.B if (isinstance(x.A, (int, float)) & isinstance(x.B, (int, float)))
else ('positive' if (isinstance(x.A, str) & (x.B == 0)) else 'negative'),
axis=1)
.replace(0, np.nan))
A      B      diff
0    20     10        10
1   NaN    NaN       NaN
2    10    NaN        10
3  give    NaN  positive
4   NaN     10       -10
5   NaN  given  negative

最新更新