После того, как вы изменили версию Java, используемую в файле POM, обновили ли вы зависимости проекта в Eclipse?
В Eclipse Luna (и, возможно, Eclipse Mars) это делается нажатием Alt-F5 или щелкнув правой кнопкой мыши проект Maven, выбрав меню Maven, а затем щелкнув кнопку «Обновить проекты».
Появится новое диалоговое окно, которое выглядит примерно так:
Все проекты Maven в текущем рабочем пространстве Eclipse должны быть показаны. В приведенном выше примере это родительский проект с несколькими дочерними проектами.
Вы должны выбрать все проекты Maven в своей рабочей области, затем нажмите OK.
Это должно заставить Maven обновить все зависимости для проекта ... включая версию Java Maven пытается использовать для проекта.
Один из методов заключается в том, чтобы сохранить результат внутренней формы слияния как dfs, тогда мы можем просто выбрать строки, когда значения одного столбца не входят в это общее:
In [119]:
common = df1.merge(df2,on=['col1','col2'])
print(common)
df1[(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))]
col1 col2
0 1 10
1 2 11
2 3 12
Out[119]:
col1 col2
3 4 13
4 5 14
EDIT
Другой метод, который вы нашли, - это использовать isin
, который приведет к появлению NaN
строк, которые вы можете удалить:
In [138]:
df1[~df1.isin(df2)].dropna()
Out[138]:
col1 col2
3 4 13
4 5 14
Однако, если df2 не запускает строки таким же образом то это не сработает:
df2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11, 12,13]})
будет генерировать весь df:
In [140]:
df1[~df1.isin(df2)].dropna()
Out[140]:
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
Как насчет этого:
df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5],
'col2' : [10, 11, 12, 13, 14]})
df2 = pandas.DataFrame(data = {'col1' : [1, 2, 3],
'col2' : [10, 11, 12]})
records_df2 = set([tuple(row) for row in df2.values])
in_df2_mask = np.array([tuple(row) in records_df2 for row in df1.values])
result = df1[~in_df2_mask]
немного поздно, но, возможно, стоит проверить параметр «индикатор» для pd.merge.
См. этот другой вопрос для примера: Сравните PandS DataFrames и возвращаемые строки, которые отсутствуют из первого
Предполагая, что индексы согласованы в кадрах данных (не принимая во внимание фактические значения col):
df1[~df1.index.isin(df2.index)]
df1
, индексы которых НЕ находятся в df2.index
». Подробнее об отрицании: stackoverflow.com/q/19960077/304209 (неожиданно, я не мог найти упоминаний тильды в документах pandas).
– Dennis Golomazov
8 June 2017 в 00:14
ValueError: Item wrong length x instead of y.
– wordsforthewise
14 September 2017 в 17:43
Предположим, что у вас есть два фрейма данных: df_1 и df_2, имеющие несколько полей (column_names), и вы хотите найти только те записи из df_1, которые не находятся в df_2, на основе некоторых полей (например, fields_x, fields_y), следуют следующему шаги.
Step1.Add столбца key1 и key2 в df_1 и df_2 соответственно.
Step2.Merge dataframes, как показано ниже. field_x и field_y - наши искомые столбцы.
Step3.Выберите только те строки из df_1, где key1 не равен key2.
Step4.Drop key1 и key2.
Этот метод позволит решить вашу проблему и быстро работать даже с большими наборами данных. Я пробовал это для dataframes с более чем 1.000.000 строк.
df_1['key1'] = 1
df_2['key2'] = 1
df_1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'left')
df_1 = df_1[~(df_1.key2 == df_1.key1)]
df_1 = df_1.drop(['key1','key2'], axis=1)
вы можете сделать это с помощью метода isin (dict) :
In [74]: df1[~df1.isin(df2.to_dict('l')).all(1)]
Out[74]:
col1 col2
3 4 13
4 5 14
Объяснение:
In [75]: df2.to_dict('l')
Out[75]: {'col1': [1, 2, 3], 'col2': [10, 11, 12]}
In [76]: df1.isin(df2.to_dict('l'))
Out[76]:
col1 col2
0 True True
1 True True
2 True True
3 False False
4 False False
In [77]: df1.isin(df2.to_dict('l')).all(1)
Out[77]:
0 True
1 True
2 True
3 False
4 False
dtype: bool
Вы также можете выполнить df1
, df2
:
x = pd.concat([df1, df2])
, а затем удалить все дубликаты:
y = x.drop_duplicates(keep=False, inplace=False)
Мой способ сделать это включает в себя добавление нового столбца, который является уникальным для одного фрейма данных, и использовать это, чтобы выбрать, сохранять ли запись
df2[col3] = 1
df1 = pd.merge(df_1, df_2, on=['field_x', 'field_y'], how = 'outer')
df1['Empt'].fillna(0, inplace=True)
. Таким образом, каждая запись в df1 имеет код - 0, если он уникален для df1, 1, если он находится в обоих файлах данных. Затем вы используете это, чтобы ограничить то, что вы хотите
answer = nonuni[nonuni['Empt'] == 0]
Как уже намечено, isin требует, чтобы столбцы и индексы были одинаковыми для соответствия. Если совпадение должно быть только в содержимом строки, одним из способов получить маску для фильтрации присутствующих строк является преобразование строк в индекс (Multi):
In [77]: df1 = pandas.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3], 'col2' : [10, 11, 12, 13, 14, 10]})
In [78]: df2 = pandas.DataFrame(data = {'col1' : [1, 3, 4], 'col2' : [10, 12, 13]})
In [79]: df1.loc[~df1.set_index(list(df1.columns)).index.isin(df2.set_index(list(df2.columns)).index)]
Out[79]:
col1 col2
1 2 11
4 5 14
5 3 10
Если индекс следует учитывать, set_index имеет аргумент ключевого слова для добавления столбцов к существующему индексу. Если столбцы не совпадают, список (df.columns) можно заменить спецификациями столбцов для выравнивания данных.
pandas.MultiIndex.from_tuples(df<N>.to_records(index = False).tolist())
можно альтернативно использовать для создания индексов, хотя я сомневаюсь, что это более эффективно .
Вот еще один способ решения этого вопроса:
df1[~df1.index.isin(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]
Или:
df1.loc[df1.index.difference(df1.merge(df2, how='inner', on=['col1', 'col2']).index)]
Выбранное в данный момент решение дает неверные результаты. Чтобы правильно решить эту проблему, мы можем выполнить левое соединение с df1
до df2
, чтобы сначала получить только уникальные строки для df2
.
Сначала давайте изменим исходный DataFrame, чтобы добавить строку с данными [3, 10].
df1 = pd.DataFrame(data = {'col1' : [1, 2, 3, 4, 5, 3],
'col2' : [10, 11, 12, 13, 14, 10]})
df2 = pd.DataFrame(data = {'col1' : [1, 2, 3],
'col2' : [10, 11, 12]})
df1
col1 col2
0 1 10
1 2 11
2 3 12
3 4 13
4 5 14
5 3 10
df2
col1 col2
0 1 10
1 2 11
2 3 12
Выполните левое объединение, исключая дубликаты в df2
, чтобы каждая строка df1
соединяется ровно с одной строкой df2
. Используйте параметр indicator
, чтобы вернуть дополнительный столбец, указывающий, из какой таблицы была строка.
df_all = df1.merge(df2.drop_duplicates(), on=['col1','col2'],
how='left', indicator=True)
df_all
col1 col2 _merge
0 1 10 both
1 2 11 both
2 3 12 both
3 4 13 left_only
4 5 14 left_only
5 3 10 left_only
Создать логическое условие:
df_all['_merge'] == 'left_only'
0 False
1 False
2 False
3 True
4 True
5 True
Name: _merge, dtype: bool
Несколько решений делают ту же ошибку - они только проверяют, что каждое значение независимо в каждом столбце, а не в одной строке. Добавление последней строки, которая является уникальной, но имеет значения из обоих столбцов из df2
, выдает ошибку:
common = df1.merge(df2,on=['col1','col2'])
(~df1.col1.isin(common.col1))&(~df1.col2.isin(common.col2))
0 False
1 False
2 False
3 True
4 True
5 False
dtype: bool
Это решение получает тот же неправильный результат
df1.isin(df2.to_dict('l')).all(1)
df1[~df1.isin(df2)].dropna(how = 'all')
, похоже, делает трюк. Спасибо в любом случае - ваш ответ помог мне найти решение. – think nice things 6 March 2015 в 16:48isin
требует, чтобы оба dfs начинались с одних и тех же значений строк, поэтому, если df2 былdf2 = pd.DataFrame(data = {'col1' : [2, 3,4], 'col2' : [11,12, 13]})
, тогда ваш метод не будет работать – EdChum 6 March 2015 в 16:504 | 13
к4.0 | 13.0
, например. Это произошло после этого шага:df1[~df1.isin(df2)].dropna()
– Chris Nielsen 8 June 2017 в 14:55