下面是我的数据框:
df = pd.DataFrame({'A': ['a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'all', 'all', 'all', 'all', 'all', 'all', 'all', 'all', 'all'],
'B': ['b1', 'b1', 'b1', 'b2', 'b2', 'b2', 'all', 'all', 'all', 'b1', 'b1', 'b1', 'b2', 'b2', 'b2', 'all', 'all', 'all'],
'C': ['c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all'],
'D': ['D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2', 'all'],
'E': ['E1', 'E1', 'E1', 'E2', 'E2', 'E2', 'all', 'all', 'all', 'E1', 'E1', 'E1', 'E2', 'E2', 'E2', 'all', 'all', 'all'],
'F': [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]})
在pivot
之后,下面是输出:
In [226]: df.pivot(index=['A', 'B', 'C'], columns=['E', 'D'])
Out[226]:
F (NO) (NO)
E E1 E1 E1 E2 E2 E2 all all all
D D1 D2 all D1 D2 all D1 D2 all
A B C
a1 all all NaN NaN NaN NaN NaN NaN NaN NaN 9.0
a1 all c1 NaN NaN NaN NaN NaN NaN 7.0 NaN NaN -> (NO)
a1 all c2 NaN NaN NaN NaN NaN NaN NaN 8.0 NaN -> (NO)
a1 b1 all NaN NaN 3.0 NaN NaN NaN NaN NaN NaN
a1 b1 c1 1.0 NaN NaN NaN NaN NaN NaN NaN NaN
a1 b1 c2 NaN 2.0 NaN NaN NaN NaN NaN NaN NaN
a1 b2 all NaN NaN NaN NaN NaN 6.0 NaN NaN NaN
a1 b2 c1 NaN NaN NaN 4.0 NaN NaN NaN NaN NaN
a1 b2 c2 NaN NaN NaN NaN 5.0 NaN NaN NaN NaN
all all all NaN NaN NaN NaN NaN NaN NaN NaN 9.0
all all c1 NaN NaN NaN NaN NaN NaN 7.0 NaN NaN -> (NO)
all all c2 NaN NaN NaN NaN NaN NaN NaN 8.0 NaN -> (NO)
all b1 all NaN NaN 3.0 NaN NaN NaN NaN NaN NaN -> (NO)
all b1 c1 1.0 NaN NaN NaN NaN NaN NaN NaN NaN -> (NO)
all b1 c2 NaN 2.0 NaN NaN NaN NaN NaN NaN NaN -> (NO)
all b2 all NaN NaN NaN NaN NaN 6.0 NaN NaN NaN -> (NO)
all b2 c1 NaN NaN NaN 4.0 NaN NaN NaN NaN NaN -> (NO)
all b2 c2 NaN NaN NaN NaN 5.0 NaN NaN NaN NaN -> (NO)
我需要删除 (NO)
指出的行和列。
逻辑是:从最里面的索引开始,即C
,我需要保留all
出现在a中的行和列落后的方式。因此,保留索引为 a1 all all
、a1 b1 all
、 a1 b2 all
和 all all all
的行因为 all
是以反向方式发生的。
索引为 a1 all c1
的行,a1 all c2
,all all c1
,all b1 all
,等需要删除,因为 all
从 C
开始向后没有连续性。
同样的逻辑也适用于列。从D
开始,需要移除索引为D1 all
和D2 all
的列,其余即可。
预期输出:
In [227]: result_df
Out[227]:
F
E E1 E1 E1 E2 E2 E2 all
D D1 D2 all D1 D2 all all
A B C
a1 all all NaN NaN NaN NaN NaN NaN 9.0
a1 b1 all NaN NaN 3.0 NaN NaN NaN NaN
a1 b1 c1 1.0 NaN NaN NaN NaN NaN NaN
a1 b1 c2 NaN 2.0 NaN NaN NaN NaN NaN
a1 b2 all NaN NaN NaN NaN NaN 6.0 NaN
a1 b2 c1 NaN NaN NaN 4.0 NaN NaN NaN
a1 b2 c2 NaN NaN NaN NaN 5.0 NaN NaN
all all all NaN NaN NaN NaN NaN NaN 9.0
更新新数据:
df = pd.DataFrame({'A': ['a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'a1', 'all', 'all', 'all', 'all', 'all',
'all::1::2', 'all::2', 'all', 'all'],
'B': ['b1', 'b1', 'b1', 'b2', 'b2', 'b2', 'all', 'all::3::4', 'all', 'b1', 'b1', 'b1', 'b2', 'b2',
'b2', 'all', 'all', 'all'],
'C': ['c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2', 'all', 'c1', 'c2',
'all', 'c1', 'c2', 'all::5::all'],
'D': ['D1', 'D2', 'all', 'D1', 'D2', 'all::3::2', 'D1', 'D2', 'all', 'D1', 'D2', 'all', 'D1', 'D2',
'all', 'D1', 'D2', 'all'],
'E': ['E1', 'E1', 'E1', 'E2', 'E2', 'E2', 'all', 'all', 'all', 'E1', 'E1', 'E1', 'E2', 'E2',
'E2', 'all::1::2', 'all', 'all'],
'measure_F': [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]})
透视
之后:
In [334]: df
Out[334]:
measure_F (NO) (NO) (NO)
E E1 E2 all E2 all::1::2
D D1 D2 all D1 D2 all::3::2 D1 D2 all all D1
A B C
a1 all all NaN NaN NaN NaN NaN NaN NaN NaN 9.0 NaN NaN
c1 NaN NaN NaN NaN NaN NaN 7.0 NaN NaN NaN NaN -> (NO)
all::3::4 c2 NaN NaN NaN NaN NaN NaN NaN 8.0 NaN NaN NaN -> (NO)
b1 all NaN NaN 3.0 NaN NaN NaN NaN NaN NaN NaN NaN
c1 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
c2 NaN 2.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
b2 all NaN NaN NaN NaN NaN 6.0 NaN NaN NaN NaN NaN
c1 NaN NaN NaN 4.0 NaN NaN NaN NaN NaN NaN NaN
c2 NaN NaN NaN NaN 5.0 NaN NaN NaN NaN NaN NaN
all all all::5::all NaN NaN NaN NaN NaN NaN NaN NaN 9.0 NaN NaN
c2 NaN NaN NaN NaN NaN NaN NaN 8.0 NaN NaN NaN -> (NO)
b1 all NaN NaN 3.0 NaN NaN NaN NaN NaN NaN NaN NaN -> (NO)
c1 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -> (NO)
c2 NaN 2.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN -> (NO)
b2 c1 NaN NaN NaN 4.0 NaN NaN NaN NaN NaN NaN NaN -> (NO)
c2 NaN NaN NaN NaN 5.0 NaN NaN NaN NaN NaN NaN -> (NO)
all::1::2 b2 all NaN NaN NaN NaN NaN NaN NaN NaN NaN 6.0 NaN -> (NO)
all::2 all c1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 7.0 -> (NO)
更新 2:
df = pd.DataFrame({'A':['test', 'test', 'test', 'test', 'test'], 'B':['a', 'b', 'c', 'd', 'e'], 'C':['x', 'x', 'all_group', 'y', 'y'], 'D':['abc', 'all_group::1::all_group', 'all_group::1::all_group', 'abc', 'abc'], 'E':[13, 36, 26, 39,40]})
In [599]: df.pivot(index=['A', 'B'], columns=['C', 'D'])
Out[599]:
E
C x all_group y
D abc all_group::1::all_group all_group::1::all_group abc
A B
test a 13.0 NaN NaN NaN
b NaN 36.0 NaN NaN
c NaN NaN 26.0 NaN
d NaN NaN NaN 39.0
e NaN NaN NaN 40.0
最佳答案
为 index
和 columns
创建掩码,帮助程序 DataFrame
最后传递给 DataFrame.loc
:
df1 = df.index.to_frame()
m1 = df1.where(df1=='all').bfill(axis=1).count(axis=1).isin([0, df.index.nlevels])
df2 = df.columns.to_frame()
m2 = df2.where(df2=='all').bfill(axis=1).count(axis=1).isin([0, df.columns.nlevels])
df = df.loc[m1, m2]
print (df)
F
E E1 E2 all
D D1 D2 all D1 D2 all all
A B C
a1 all all NaN NaN NaN NaN NaN NaN 9.0
b1 all NaN NaN 3.0 NaN NaN NaN NaN
c1 1.0 NaN NaN NaN NaN NaN NaN
c2 NaN 2.0 NaN NaN NaN NaN NaN
b2 all NaN NaN NaN NaN NaN 6.0 NaN
c1 NaN NaN NaN 4.0 NaN NaN NaN
c2 NaN NaN NaN NaN 5.0 NaN NaN
all all all NaN NaN NaN NaN NaN NaN 9.0
b1 all NaN NaN 3.0 NaN NaN NaN NaN
b2 all NaN NaN NaN NaN NaN 6.0 NaN
详细信息:
使用MultiIndex.to_frame
对于 DataFrame
:
print (df.index.to_frame())
A B C
A B C
a1 all all a1 all all
c1 a1 all c1
c2 a1 all c2
b1 all a1 b1 all
c1 a1 b1 c1
c2 a1 b1 c2
b2 all a1 b2 all
c1 a1 b2 c1
c2 a1 b2 c2
all all all all all all
c1 all all c1
c2 all all c2
b1 all all b1 all
c1 all b1 c1
c2 all b1 c2
b2 all all b2 all
c1 all b2 c1
c2 all b2 c2
然后用 DataFrame.where
将非 all
替换为缺失值:
print (df1.where(df1=='all'))
A B C
A B C
a1 all all NaN all all
c1 NaN all NaN
c2 NaN all NaN
b1 all NaN NaN all
c1 NaN NaN NaN
c2 NaN NaN NaN
b2 all NaN NaN all
c1 NaN NaN NaN
c2 NaN NaN NaN
all all all all all all
c1 all all NaN
c2 all all NaN
b1 all all NaN all
c1 all NaN NaN
c2 all NaN NaN
b2 all all NaN all
c1 all NaN NaN
c2 all NaN NaN
回填不误,这里是all
,by bfill
:
print (df1.where(df1=='all').bfill(axis=1))
A B C
A B C
a1 all all all all all
c1 all all NaN
c2 all all NaN
b1 all all all all
c1 NaN NaN NaN
c2 NaN NaN NaN
b2 all all all all
c1 NaN NaN NaN
c2 NaN NaN NaN
all all all all all all
c1 all all NaN
c2 all all NaN
b1 all all all all
c1 all NaN NaN
c2 all NaN NaN
b2 all all all all
c1 all NaN NaN
c2 all NaN NaN
按 DataFrame.count
计算非缺失值:
print (df1.where(df1=='all').bfill(axis=1).count(axis=1))
A B C
a1 all all 3
c1 2
c2 2
b1 all 3
c1 0
c2 0
b2 all 3
c1 0
c2 0
all all all 3
c1 2
c2 2
b1 all 3
c1 1
c2 1
b2 all 3
c1 1
c2 1
测试 0
- 这意味着回填行/列,如果所有 NaN
它与级别数匹配 MultiIndex.nlevels
:
print (df1.where(df1=='all').bfill(axis=1).count(axis=1).isin([0, df.index.nlevels]))
A B C
a1 all all True
c1 False
c2 False
b1 all True
c1 True
c2 True
b2 all True
c1 True
c2 True
all all all True
c1 False
c2 False
b1 all True
c1 False
c2 False
b2 all True
c1 False
c2 False
dtype: bool
编辑:这里是比较子字符串,然后是 np.triu
创建的辅助数组的掩码的所有值,这些辅助数组仅与 False
的行链接:
f = lambda x: x.str.contains('all')
arr1 = np.triu(np.ones((df.index.nlevels,df.index.nlevels), dtype=bool), False)
arr2 = np.triu(np.ones((df.columns.nlevels,df.columns.nlevels), dtype=bool), False)
print (arr1)
[[ True True True]
[False True True]
[False False True]]
arr11 = df.index.to_frame().astype(str).apply(f).to_numpy()
arr22 = df.columns.to_frame().astype(str).apply(f).to_numpy()
#https://stackoverflow.com/a/51352806/2901002
m1 = (arr11[:, None] == arr1).all(-1).any(axis=1) | ~arr11.any(axis=1)
m2 = (arr22[:, None] == arr2).all(-1).any(axis=1) | ~arr22.any(axis=1)
df = df.loc[m1, m2]
print (df)
measure_F
E E1 E2 all E2
D D1 D2 all D1 D2 all::3::2 all all
A B C
a1 all all NaN NaN NaN NaN NaN NaN 9.0 NaN
b1 all NaN NaN 3.0 NaN NaN NaN NaN NaN
c1 1.0 NaN NaN NaN NaN NaN NaN NaN
c2 NaN 2.0 NaN NaN NaN NaN NaN NaN
b2 all NaN NaN NaN NaN NaN 6.0 NaN NaN
c1 NaN NaN NaN 4.0 NaN NaN NaN NaN
c2 NaN NaN NaN NaN 5.0 NaN NaN NaN
all all all::5::all NaN NaN NaN NaN NaN NaN 9.0 NaN
关于python - Pandas:根据复杂逻辑删除具有特定字符串的行和列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64330560/