2016-05-09 2 views
2

Учитывая pandas.DataFrame:Удалить строки из pandas.Dataframe На основании записей

| Col_A | Col_B | Other_Columns 
0 | A0 | B0 | … 
1 | A1 | B1 | … 
2 | A2 | B2 | … 
3 | A3 | B3 | … 
… | …  | …  | … 

Я пытался сохранить часть этой DataFrame: чтобы избавиться от строк, где оба A и B записей являются уникальными (например, если на 6-й строке сказать, оба значения A6 и B6 не появляются в другом месте на DataFrame, мы хотим, чтобы удалить эту строку)

Я не хотел бы отказаться от дубликатов. Кроме того, я не хотел бы получать уникальные значения (которые, если я хорошо понимаю, были бы похожи на преобразование списка в набор, я прав?), А вместо этого значения, которые появляются только один раз.

На данный момент, это то, что я получил:

counts = df[['Col_A','Col_B']].stack().value_counts(ascending=True) 
myList = [0] + [item for item in counts[counts.values == 1].index] 
toRemove = [] 
for i in df.index: 
    if (df.at[i,'Col_A'] and df.at[i, 'Col_B']) in myList: 
     toRemove.append(i) 
final_df = df[~df.index.isin(toRemove)] 

Это не очень эффективно (кадр данных довольно большая> 10M линия) Там должна быть более вещими стратегии, включая встроенные функции панды, правильно? Кроме того, я не уверен, что первая строка верна: путем укладки обоих столбцов я уверен, что вы выполняете подсчет по элементам обоих столбцов?

Пожалуйста, не стесняйтесь, если вам нужна дополнительная информация или если мое письмо вам нечеткое.

Большое спасибо, что нашли время :-)

+0

@unutbu, ИМО это не дубликат. OP хочет сохранить строки, где значения в столбце __either__ не уникальны. – MaxU

+0

@MaxU: Моя ошибка; спасибо за повторное открытие. – unutbu

ответ

1

, что о чем-то вроде этого:

In [75]: df = pd.DataFrame(np.random.randint(0,100,size=(10, 3)), columns=list('abc')) 

In [76]: df 
Out[76]: 
    a b c 
0 37 85 17 
1 19 0 11 
2 51 20 65 
3 59 92 65 
4 48 15 91 
5 21 50 44 
6 61 94 49 
7 51 6 88 
8 89 72 40 
9 5 51 79 

In [77]: c = df[['a','b']].stack().value_counts() 

In [78]: c 
Out[78]: 
51 3 
94 1 
15 1 
37 1 
6  1 
72 1 
50 1 
21 1 
5  1 
48 1 
61 1 
19 1 
20 1 
85 1 
89 1 
59 1 
92 1 
0  1 
dtype: int64 

In [79]: c[c>1] 
Out[79]: 
51 3 
dtype: int64 

In [80]: vals = c[c>1].index 

In [81]: df[(df['a'].isin(vals)) | (df['b'].isin(vals))] 
Out[81]: 
    a b c 
2 51 20 65 
7 51 6 88 
9 5 51 79 

UPDATE:

когда вы делаете if (df.at[i,'Col_A'] and df.at[i, 'Col_B']) in myList: проверки вы проверяете его не совсем правильно ...

вот что происходит:

In [90]: df.at[0, 'a'], df.at[0, 'b'] 
Out[90]: (37, 85) 

In [91]: (df.at[0, 'a'] and df.at[0, 'b']) 
Out[91]: 85 

Таким образом, вы не можете проверить это следующим образом

+0

Большое спасибо MaxU, ваш предложенный ответ ясен и ваш код быстро. Я играл с ним, но один сомнения остается: я получаю совершенно другой результат, если я пытаюсь сделать это с медленным приближением цикла по индексам кадра данных: 'keepIndex = []' 'для я в df.index: , если df.at [я, 'а'] или df.at [я, 'б'] в вальсе: keepIndex.append (я)' 'final_df = DF [ df.index.isin (keepIndex)] ' Является ли мой код совершенно другим? Я что-то пропустил? – UniversalTraveller

+0

@UniversalTraveller, пожалуйста, прочтите раздел «ОБНОВЛЕНИЕ:» в моем ответе – MaxU

+0

Хорошо, спасибо за разъяснение :-) Насколько это возможно, вы знаете почему? – UniversalTraveller

Смежные вопросы