[英]More pythonic way to remove rows where one value begins by another row's value in a pandas dataframe
[英]What is the best way to remove all elements in a pandas dataframe where a value in one columns exists more than once in another column?
我有一个由几棵树组成的 DataFrame。 我想删除在ToNode
列中多次出现RootNode
所有行。 但是, ToNode
的节点可以出现多次,如果它不是根节点。
这是 df 的一个例子。
ToNode | FromNode | Root
A None A
B A A
C None C
A C C
B A C
在这里,我想删除Root == A
所有行,以便生成的 df 是
ToNode | FromNode | Root
C None C
A C C
B A C
实现此目的的一种方法(非常慢)如下:
root_list = list(df['Root'].unique())
for node in root_list:
if len(df[df['ToNode'] == node]) > 1:
df = df[df['Root'] != node]
我想有一种更快的方法,也许使用groupby()
和transform()
和/或map
/ apply
。
任何人都有关于如何加快速度的任何提示?
首先使用 groupby 找到所有出现>1
ToNode
并在Root
上过滤df
df2 = df.groupby(['ToNode'], as_index=False).count()
df[~df['Root'].isin(df2[df2['Root'] > 1]['ToNode'].unique())]
这给你以下结果。
ToNode FromNode Root
2 C None C
3 A C C
4 B A C
您可以尝试以下操作。
value_counts
获取计数>>> df.apply(pd.Series.value_counts, axis=1)[['A']] >= 2
A
0 True
1 True
2 False
3 False
4 False
>>> mask = df.apply(pd.Series.value_counts, axis=1)[['A']] >= 2
>>> mask[mask.A].index
Int64Index([0, 1], dtype='int64')
>>> idx = mask[mask.A].index
>>> df.drop(idx)
ToNode FromNode Root
2 C None C
3 A C C
4 B A C
您可以将Series.value_counts
和Series.isin
与布尔索引一起使用。 ~
这里是逻辑NOT
:
nodes_to_remove = df['ToNode'].value_counts()[lambda x: x > 1].index
#print(nodes_to_remove) Index(['A', 'B'], dtype='object')
df[~df['Root'].isin(nodes_to_remove)]
[出去]
ToNode FromNode Root
2 C None C
3 A C C
4 B A C
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.