Pandon Pandas Проверьте, является ли значение в Dataframe [дубликат]

ECMAScript 6 имеет «генераторы», которые позволяют вам легко программировать в асинхронном стиле.

function* myGenerator() {
    const callback = yield;
    let [response] = yield $.ajax("https://stackoverflow.com", {complete: callback});
    console.log("response is:", response);

    // examples of other things you can do
    yield setTimeout(callback, 1000);
    console.log("it delayed for 1000ms");
    while (response.statusText === "error") {
        [response] = yield* anotherGenerator();
    }
}

Для запуска вышеуказанного кода вы делаете это:

const gen = myGenerator(); // Create generator
gen.next(); // Start it
gen.next((...args) => gen.next([...args])); // Set its callback function

Если вам нужно настроить таргетинг на браузеры, которые не поддерживают ES6, вы можете запустить код через Babel или short-compiler для генерации ECMAScript 5.

Обратный вызов ...args завернут в массив и разрушен, когда вы их читаете так что шаблон может справиться с обратными вызовами, которые имеют несколько аргументов. Например, с узлом fs :

const [err, data] = yield fs.readFile(filePath, "utf-8", callback);

20
задан W R 6 April 2015 в 20:39
поделиться

2 ответа

Одно из возможных решений вашей проблемы - использовать merge . Проверка наличия любой строки (всех столбцов) из другого фрейма данных (df2) в df1 эквивалентна определению пересечения двух данных. Это может быть выполнено с помощью следующей функции:

pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner')

Например, если df1 был

    A           B            C          D
0   0.403846    0.312230    0.209882    0.397923
1   0.934957    0.731730    0.484712    0.734747
2   0.588245    0.961589    0.910292    0.382072
3   0.534226    0.276908    0.323282    0.629398
4   0.259533    0.277465    0.043652    0.925743
5   0.667415    0.051182    0.928655    0.737673
6   0.217923    0.665446    0.224268    0.772592
7   0.023578    0.561884    0.615515    0.362084
8   0.346373    0.375366    0.083003    0.663622
9   0.352584    0.103263    0.661686    0.246862

, а df2 был определен как:

     A          B            C           D
0   0.259533    0.277465    0.043652    0.925743
1   0.667415    0.051182    0.928655    0.737673
2   0.217923    0.665446    0.224268    0.772592
3   0.023578    0.561884    0.615515    0.362084
4   0.346373    0.375366    0.083003    0.663622
5   2.000000    3.000000    4.000000    5.000000
6   14.000000   15.000000   16.000000   17.000000

Функция pd.merge(df1, df2, on=['A', 'B', 'C', 'D'], how='inner') производит:

     A           B           C           D
0   0.259533    0.277465    0.043652    0.925743
1   0.667415    0.051182    0.928655    0.737673
2   0.217923    0.665446    0.224268    0.772592
3   0.023578    0.561884    0.615515    0.362084
4   0.346373    0.375366    0.083003    0.663622

Результаты - это все строки (все столбцы), которые находятся как в df1, так и в df2.

Мы также можем изменить этот пример если столбцы не совпадают в df1 и df2 и просто сравнивают значения строк, которые одинаковы для подмножества столбцов. Если мы изменим исходный пример:

df1 = pd.DataFrame(np.random.rand(10,4),columns=list('ABCD'))
df2 = df1.ix[4:8]
df2.reset_index(drop=True,inplace=True)
df2.loc[-1] = [2, 3, 4, 5]
df2.loc[-2] = [14, 15, 16, 17]
df2.reset_index(drop=True,inplace=True)
df2 = df2[['A', 'B', 'C']] # df2 has only columns A B C

Затем мы можем посмотреть на общие столбцы, используя common_cols = list(set(df1.columns) & set(df2.columns)) между двумя файлами данных, затем слить:

pd.merge(df1, df2, on=common_cols, how='inner')

EDIT: новый вопрос (комментарии), идентифицировав строки из df2, которые также присутствовали в первом фрейме данных (df1), можно взять результат pd.merge () и затем отбросить строки из df2, которые также присутствуют в df1

Я не знаю простого способа выполнить задачу по удалению строк из df2, которые также присутствуют в df1. Тем не менее, вы можете использовать следующее:

ds1 = set(tuple(line) for line in df1.values)
ds2 = set(tuple(line) for line in df2.values)
df = pd.DataFrame(list(ds2.difference(ds1)), columns=df2.columns)

Вероятно, существует лучший способ выполнить эту задачу, но я не знаю о таком методе / функции.

РЕДАКТИРОВАТЬ 2: Как удалить строки из df2, которые также присутствуют в df1, как показано в ответе @WR.

Предоставленный метод df2[~df2['A'].isin(df12['A'])] не учитывает все типы ситуации. Рассмотрим следующие DataFrames:

df1:

   A  B  C  D
0  6  4  1  6
1  7  6  6  8
2  1  6  2  7
3  8  0  4  1
4  1  0  2  3
5  8  4  7  5
6  4  7  1  1
7  3  7  3  4
8  5  2  8  8
9  3  2  8  4

df2:

   A  B  C  D
0  1  0  2  3
1  8  4  7  5
2  4  7  1  1
3  3  7  3  4
4  5  2  8  8
5  1  1  1  1
6  2  2  2  2

df12:

   A  B  C  D
0  1  0  2  3
1  8  4  7  5
2  4  7  1  1
3  3  7  3  4
4  5  2  8  8

Использование выше DataFrames с целью удаления строк из df2, которые также присутствуют в df1, приведет к следующему:

   A  B  C  D
0  1  1  1  1
1  2  2  2  2

Строки (1, 1, 1, 1) и (2, 2, 2, 2) находятся в df2, а не в df1. К сожалению, использование предоставленного метода (df2[~df2['A'].isin(df12['A'])]) приводит к:

   A  B  C  D
6  2  2  2  2

Это происходит из-за того, что значение 1 в столбце A находится как в пересечении DataFrame (т.е. (1, 0, 2, 3)) и df2 и таким образом удаляет оба (1, 0, 2, 3) и (1, 1, 1, 1). Это непреднамеренно, так как строка (1, 1, 1, 1) не находится в df1 и не должна удаляться.

Я думаю, что следующее будет служить решением. Он создает фиктивный столбец, который позже используется для подмножества DataFrame с желаемыми результатами:

df12['key'] = 'x'
temp_df = pd.merge(df2, df12, on=df2.columns.tolist(), how='left')
temp_df[temp_df['key'].isnull()].drop('key', axis=1)
29
ответ дан Andrew 25 August 2018 в 05:41
поделиться

@Andrew: Я считаю, что нашел способ отбросить строки одного кадра данных, которые уже присутствуют в другом (т. е. отвечать на мой EDIT), без использования циклов - сообщите мне, если вы не согласны и / или если мой OP + EDIT не ясно это сказал:

ЭТО РАБОТЫ

Столбы для обоих кадров данных всегда одинаковы - A, B, C и D. Имея это в виду, в основе которого лежит подход Андрея, вот как удалить строки из df2, которые также присутствуют в df1:

common_cols = df1.columns.tolist()                         #generate list of column names
df12 = pd.merge(df1, df2, on=common_cols, how='inner')     #extract common rows with merge
df2 = df2[~df2['A'].isin(df12['A'])]

Строка 3 выполняет следующие действия:

  • Извлеките только строки из df2, которые не соответствуют строкам в df1:
  • Для того, чтобы две строки были разными, ЛЮБОЙ один столбец из одной строки обязательно должен быть разным что соответствующий столбец в другой строке.
  • Здесь я выбрал столбец A, чтобы сделать это сравнение - можно использовать любые имена столбцов, но не ВСЕ имена столбцов.

ПРИМЕЧАНИЕ. Этот метод по существу является эквивалентом SQL NOT IN().

8
ответ дан W R 25 August 2018 в 05:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: