我有两个pandas数据框A
和B
。 B
是A的子集。
我想删除A中的所有数字,如果它在B中但,如果一个数字在A中出现两次,在B中出现1次,那么它只会删除1次出现的数字来自A的数字。
以下是我的示例数据集:
df_A df_B
[Test] [Test]
1 1
2 2
3 5
2 5
4
5
5
操作后我想要新的数据框c为
df_C
[Test]
3
2
4
你能建议怎么做吗?
如果A
中存在B
,suggested duplicate将删除public abstract class ClassA
{
private int m_number;
protected ClassA()
{
m_number = GetNumber()
}
protected abstract int GetNumber();
}
public class ClassB : ClassA
{
public ClassB() : base()
{
}
protected override int GetNumber()
{
return 10;
}
}
中的所有匹配项,而不仅仅是前N次出现。
答案 0 :(得分:2)
如果您创建一些包含每个值的出现次数的中间值,则可以使用pandas.Series.isin()
创建要排除的数据帧的哪些行的逻辑索引,如:
from collections import Counter
def occurrences_number(column):
def occurrence_number(value, accumulator):
""" tuple of value and occurrence number of value """
accumulator[value] += 1
return value, accumulator[value]
occurrences = Counter()
return column.apply(lambda x: occurrence_number(x, occurrences))
def find_not_in_by_occurrence_number(data, not_in):
not_in_indices = ~occurrences_number(data).isin(occurrences_number(not_in))
return data[not_in_indices].reset_index()
import pandas as pd
dfA = pd.DataFrame({'A': [1, 2, 3, 2, 4, 5, 5]})
dfB = pd.DataFrame({'B': [1, 2, 5, 5]})
print(dfA)
print(dfB)
dfC = find_not_in_by_occurrence_number(dfA.A, dfB.B).A
print (dfC)
A
0 1
1 2
2 3
3 2
4 4
5 5
6 5
B
0 1
1 2
2 5
3 5
0 3
1 2
2 4
Name: A, dtype: int64
答案 1 :(得分:2)
我可能会做某事(窃取SR的设置):
dfA = pd.DataFrame({'A': [1, 2, 3, 2, 4, 5, 5]})
dfB = pd.DataFrame({'B': [1, 2, 5, 5]})
counts = dfA.groupby('A').cumcount()
limits = dfB['B'].value_counts().reindex(dfA.A).fillna(0).values
dfC = dfA.loc[counts >= limits]
给了我
In [121]: dfC
Out[121]:
A
2 3
3 2
4 4
这可以通过使用groupby来获得之前看到A中给定值的次数:
In [124]: dfA.groupby('A').cumcount()
Out[124]:
0 0
1 0
2 0
3 1
4 0
5 0
6 1
dtype: int64
并使用value_counts
获取限制,然后重新索引以匹配计数:
In [139]: dfB['B'].value_counts()
Out[139]:
5 2
2 1
1 1
Name: B, dtype: int64
In [140]: dfB['B'].value_counts().reindex(dfA.A)
Out[140]:
A
1 1.0
2 1.0
3 NaN
2 1.0
4 NaN
5 2.0
5 2.0
Name: B, dtype: float64
答案 2 :(得分:1)
在此问题中,您可以使用Counter
和drop
。对于drop,您需要知道要丢弃的行的索引。
import itertools
from collections import Counter
df = pd.DataFrame({'Test': {0: 1, 1: 2, 2: 3, 3: 2, 4: 4, 5: 5, 6: 5}})
df2 = pd.DataFrame({'Test': {0: 1, 1: 2, 2: 5, 3: 5}})
c_df2 = Counter(df2.Test)
indexes_to_remove_2d = [df.index[df['Test'] == k].tolist()[:v]
for k, v in c_df2.items()]
# [[0], [1], [5, 6]]
merged = list(itertools.chain(*indexes_to_remove_2d))
# [0, 1, 5, 6]
df.drop(merged)
Test
2 3
3 2
4 4
indexes_2d
生成符合k
计数器值df.index[df['Test'] == k]
的索引,并且[:v]
限制我们从中获取的索引的大小。
然后,我们将这些indexes
与itertools.chain
合并。最后删除带有这些索引的行。
感谢Stephan Ranch指出订单问题。