繁体   English   中英

删除 Pandas 数据框中的非等效多索引行

[英]Drop Non-equivalent Multiindex Rows in Pandas Dataframe

目标

如果 sub-column min等于 sub-column max并且如果minmax sub-column 在任何列中都不相等(在这种情况下是 ao、his、cyp1a2s、cyp3a4s),则删除该行。

例子

arrays = [np.array(['ao', 'ao', 'hia', 'hia', 'cyp1a2s', 'cyp1a2s', 'cyp3a4s', 'cyp3a4s']),
          np.array(['min', 'max', 'min', 'max', 'min', 'max', 'min', 'max'])]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['',''])
df = pd.DataFrame(np.array([[1, 1, 0, 0, float('nan'), float('nan'), 0, 0], 
                            [1, 1, 0, 0, float('nan'), 1, 0, 0],
                            [0, 2, 0, 0, float('nan'), float('nan'), 1, 1],]), index=['1', '2', '3'], columns=index)
df

    ao      hia     cyp1a2s cyp3a4s
    min max min max min max min max
1   1.0 1.0 0.0 0.0 NaN NaN 0.0 0.0
2   1.0 1.0 0.0 0.0 NaN 1.0 0.0 0.0
3   0.0 2.0 0.0 0.0 NaN NaN 1.0 1.0

df = pd.DataFrame(np.array([[1, 1, 0, 0, float('nan'), float('nan'), 0, 0]]), index=['1'], columns=index)
df

    ao      hia     cyp1a2s cyp3a4s
    min max min max min max min max
1   1.0 1.0 0.0 0.0 NaN NaN 0.0 0.0

试图

df.apply(lambda x: x['min'].map(str) == x['max'].map(str), axis=1)

KeyError: ('min', 'occurred at index 1')

笔记

实际的数据框有 50 多列。

DataFrame.xs用于DataFrame的第二级MultiIndex ,替换NaN s:

df1 = df.xs('min', axis=1, level=1).fillna('nan')
df2 = df.xs('max', axis=1, level=1).fillna('nan')

或将数据转换为字符串:

df1 = df.xs('min', axis=1, level=1).astype('str')
df2 = df.xs('max', axis=1, level=1).astype('str')

比较Dataframes通过DataFrame.eq如果所有测试True S按DataFrame.all和最后一个过滤器boolean indexing

df = df[df1.eq(df2).all(axis=1)]
print (df)
    ao       hia      cyp1a2s     cyp3a4s     
   min  max  min  max     min max     min  max
1  1.0  1.0  0.0  0.0     NaN NaN     0.0  0.0

df.apply() 不起作用的原因是您需要引用 2 个级别的列。

此外 .map(str) 对从 float64 映射无效...使用 .astype(str)

以下适用于 >1 列:

eqCols = ['cyp1a2s','hia']
neqCols = list(set(df.xs('min', level=1, axis=1).columns) - set(eqCols))
EQ = lambda r,c : r[c]['min'].astype(str) == r[c]['max'].astype(str)
df[df.apply(lambda r: ([EQ(r,c) for c in eqCols][0]) & ([(not EQ(r,c)) for c in neqCols][0]), axis=1)]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM