Как объединить два кадра данных и вернуть данные из другого столбца в новый столбец только при наличии совпадения? - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть два df, которые выглядят так:

df1:

id
1
2


df2:

id    value
2       a
3       b

Как объединить эти два кадра данных и вернуть данные только из столбца value в новый столбец, если есть совпадение?

new_merged_df

id   value   new_value
1
2     a         a
3     b

Ответы [ 5 ]

0 голосов
/ 14 ноября 2018

DataFrame.merge имеет параметр indicator, который

Если True, добавляет к выходному столбцу DataFrame столбец с именем _merge с информацией об источнике каждой строки.

Это можно использовать для проверки соответствия

import pandas as pd

df1 = pd.DataFrame(index=[1,2])
df2 = pd.DataFrame({'value' : ['a','b']},index=[2,3])

# creates a new column `_merge` with values `right_only`, `left_only` or `both`
merged = df1.merge(df2, how='outer', right_index=True, left_index=True, indicator=True) 
merged['new_value'] = merged.loc[(merged['_merge'] == 'both'), 'value']
merged = merged.drop('_merge', axis=1)
0 голосов
/ 14 ноября 2018

Вы можете использовать full outer join

Позволяет моделировать ваши данные с помощью классов дел:

case class MyClass1(id: String)
case class MyClass2(id: String, value: String)

//  this one for the result type
case class MyClass3(id: String, value: Option[String] = None, value2: Option[String] = None)

Создание нескольких входных данных:

val input1: Dataset[MyClass1] = ...
val input2: Dataset[MyClass2] = ...

Объединение ваших данных:

import scala.implicits._
val joined = input1.as("1").joinWith(input2.as("2"), $"1.id" === $"2.id", "full_outer")

joined map {
  case (left, null) if left != null => MyClass3(left.id)
  case (null, right) if right != null => MyClass3(right.id, Some(right.value))
  case (left, right) => MyClass3(left.id, Some(right.value), Some(right.value))
}
0 голосов
/ 14 ноября 2018

Вы можете попробовать это, используя @ JJFord3 setup:

import pandas

df1 = pandas.DataFrame(index=[1,2])
df2 = pandas.DataFrame({'value' : ['a','b']},index=[2,3])

#Use isin to create new_value   
df2['new_value'] = df2['value'].where(df2.index.isin(df1.index))
#Use reindex with union to rebuild dataframe with both indexes
df2.reindex(df1.index.union(df2.index))

Выход:

  value new_value
1   NaN       NaN
2     a         a
3     b       NaN
0 голосов
/ 14 ноября 2018

Использование merge и isin:

df = df1.merge(df2,on='id',how='outer')

id_value = df2.loc[df2['id'].isin(df1.id.tolist()),'id'].unique()
mask = df['id'].isin(id_value)
df.loc[mask,'new_value'] = df.loc[mask,'value']
# alternative df['new_value'] = np.where(mask, df['value'], np.nan)    

print(df)
   id value new_value
0   1   NaN       NaN
1   2     a         a
2   3     b       NaN
0 голосов
/ 14 ноября 2018
import pandas

df1 = pandas.DataFrame(index=[1,2])
df2 = pandas.DataFrame({'value' : ['a','b']},index=[2,3])

new_merged_df_outer = df1.merge(df2,how='outer',left_index=True,right_index=True)
new_merged_df_inner = df1.merge(df2,how='inner',left_index=True,right_index=True)
new_merged_df_inner.rename(columns={'value':'new_value'})
new_merged_df = new_merged_df_outer.merge(new_merged_df_inner,how='left',left_index=True,right_index=True)

Сначала создайте внешнее объединение, чтобы сохранить все индексы. Затем создайте внутреннее слияние, чтобы получить только перекрытие. Затем объедините внутреннее объединение с внешним объединением, чтобы получить желаемую настройку столбца.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...