上下文是我想比较两个df并找出差异。
这里的df和df2差别很小:
df = pd.DataFrame({'a': range(3),
'b': range(3)})
df2 = df.copy()
df2.iloc[1,1] = 100
比较它们会产生相同形状的2D布尔df:
df != df2
Out[28]:
a b
0 False False
1 False True
2 False False
我尝试提取与True对应的元素,但其他元素(我不希望)仍然以NaN出现
df[df != df2]
Out[29]:
a b
0 NaN NaN
1 NaN 1.0
2 NaN NaN
如何仅提取与True和索引相对应的元素(所以我知道df中的位置):
df[df != df2] # somehow?
Out[30]:
b
1 1.0
更新:上面的示例只有一个True。在具有多个True的一般情况下,我认为有两种情况:
df很小,您可能想看看:
df = pd.DataFrame({'a': range(3),
'b': range(3)})
df2 = df.copy()
df2.iloc[0,0] = 100
df2.iloc[1,1] = 100
df[df!=df2].dropna(how='all',axis=(0,1)) # U9-Forward's answer
Out[39]:
a b
0 0.0 NaN
1 NaN 1.0
df很大,您可能想看看:
index column df_value df2_value
0 a 0.0 100
1 b 1.0 100
@ U9-Forward的答案在情况1以及只有一个True的情况下效果很好。
@coldspeed提供了全面的解决方案。谢谢!
答案 0 :(得分:3)
屏蔽值:
df.values[df != df2]
# array([1])
该如何处理?
df2.at[0, 'a'] = 100
df
a b
0 0 0
1 1 1
2 2 2
df2
a b
0 100 0
1 1 100
2 2 2
df != df2
a b
0 True False
1 False True
2 False False
df.values[df != df2]
# array([0, 1])
# in the other answer
df[df!=df2].dropna(how='all',axis=(0,1))
a b
0 0.0 NaN
1 NaN 1.0
所需的输出是什么?
如果您只是df
的每一列中的值都不同,则类似agg
和dropna
这样的简单操作就可以。
df[df != df2].agg(lambda x: x.dropna().tolist())
a [0.0]
b [1.0]
dtype: object
如果需要索引和列,请使用melt
:
u = df2.reset_index().melt('index')
v = df.reset_index().melt('index')
u[u['value'] != v['value']]
index variable value
0 0 a 100
4 1 b 100
或者,使用np.nonzero
对numpy进行此操作-真值为非零,这些索引将返回。
m = (df != df2).values
idx, cols = np.nonzero(m)
pd.DataFrame({
'index': df.index.values[idx],
'column': df.columns.values[cols],
'value_1': df.values[m],
'value_2': df2.values[m]
})
index column value_1 value_2
0 0 a 0 100
1 1 b 1 100
答案 1 :(得分:2)
使用条件,然后输入dropna
:
print(df[df!=df2].dropna(how='all',axis=(0,1)))
答案 2 :(得分:1)
如果要获取有关索引和列的信息,请为MultiIndex Series
添加stack
:
df = pd.DataFrame({'a': range(3),
'b': range(3)})
df2 = df.copy()
df2.iloc[1,1] = 100
df2.iloc[0,0] = 100
s = df.stack()
s2 = df2.stack()
out = s[s != s2].rename_axis(['idx','col']).reset_index(name='val')
print (out)
idx col val
0 0 a 0
1 1 b 1
out2 = s2[s != s2].rename_axis(['idx','col']).reset_index(name='val')
print (out2)
idx col val
0 0 a 100
1 1 b 100
或将numpy indexing
与numpy.where
一起用于True
值的索引:
mask = df != df2
a = np.where(mask)
out = pd.DataFrame({'idx': df.index.values[a[0]],
'cols': df.columns.values[a[1]],
'vals_df': df.values[mask],
'vals_df2': df2.values[mask]})
print (out)
idx cols vals_df vals_df2
0 0 a 0 100
1 1 b 1 100
答案 3 :(得分:1)
numpy解决方案:
mask = df2[df!=df2]
a = mask.values
这将返回一个数组。
x = a[~np.isnan(a)].astype(int)
>>x
array([100])
答案 4 :(得分:1)
您可以使用melt,然后为不同的值进行过滤:
viewWillAppear: