Pandas разделить два кадра данных с разными размерами - PullRequest
0 голосов
/ 19 января 2020

У меня есть датафрейм df1 как:

col1 col2 Val1 Val2
A    g    4    6
A    d    3    8
B    h    5    10
B    p    7    14

У меня есть другой фрейм данных df2 как:

col1 Val1 Val2
A    2    3
B    1    4

Я хочу разделить df1 на df2 на основе col1, val1 и val2 так эта строка A из df2 делит обе строки A из df1.

Мой окончательный вывод df1.div(df2) выглядит следующим образом:

col1 col2 Val1 Val2
A    g    2    2
A    d    1.5  2
B    h    5    2.5
B    p    7    3.5

Ответы [ 3 ]

2 голосов
/ 19 января 2020

Преобразование col1 и col2 в MultiIndex, также преобразование col1 в секунду DataFrame в индекс и затем использование DataFrame.div:

df = df1.set_index(['col1', 'col2']).div(df2.set_index('col1')).reset_index()
#alternative with specify level of index
#df = df1.set_index(['col1', 'col2']).div(df2.set_index('col1'), level=0).reset_index()
print (df)
  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000
1 голос
/ 19 января 2020

Я думаю, что в вашем примере есть небольшая ошибка. Для col Val2, 2-й ряд - 8/3 должен быть 2,67. Таким образом, конечный результат df1.div(df2) должен быть:

  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000

В любом случае здесь возможное решение:

  1. Построить 2 dfs
import pandas as pd

df1 = pd.DataFrame(data={'col1':['A','A','B','B'], 'col2': ['g','d','h','p'], 'Val1': [4,3,5,7], 'Val2': [6,8,10,14]}, columns=['col1','col2','Val1','Val2'])

df2 = pd.DataFrame(data={'col1':['A','B'], 'Val1': [2,1], 'Val2': [3,4]}, columns=['col1','Val1','Val2'])

print (df1)
print (df2)

Вывод:

>>>
col1 col2  Val1  Val2
0    A    g     4     6
1    A    d     3     8
2    B    h     5    10
3    B    p     7    14

  col1  Val1  Val2
0    A     2     3
1    B     1     4

Теперь мы можем просто сделать INNER JOIN из df1 и df2 для столбца: col1. Если вы не знакомы с SQL объединениями, взгляните на это: sql -join . Мы можем присоединиться к pandas, используя merge() метод

## join df1, df2

merged_df = pd.merge(left=df1, right=df2, how='inner', on='col1')

print (merged_df)

Вывод:

>>>
col1 col2  Val1_x  Val2_x  Val1_y  Val2_y
0    A    g       4       6       2       3
1    A    d       3       8       2       3
2    B    h       5      10       1       4
3    B    p       7      14       1       4

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

# Val1 = Val1_x/Val1_y, Val2 = Val2_x/Val2_y

merged_df['Val1'] = merged_df['Val1_x']/merged_df['Val1_y']
merged_df['Val2'] = merged_df['Val2_x']/merged_df['Val2_y']

# delete the cols: Val1_x,Val1_y,Val2_x,Val2_y

merged_df.drop(columns=['Val1_x', 'Val1_y', 'Val2_x', 'Val2_y'], inplace=True)

print (merged_df)

Окончательный вывод:

  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000

Надеюсь, это решит ваш вопрос :)

1 голос
/ 19 января 2020

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

# merge against col1 so we get a merged index
merged = pd.merge(df1[["col1"]], df2)
df1[["Val1", "Val2"]] = df1[["Val1", "Val2"]].div(merged[["Val1", "Val2"]])

Это производит:

  col1 col2  Val1      Val2
0    A    g   2.0  2.000000
1    A    d   1.5  2.666667
2    B    h   5.0  2.500000
3    B    p   7.0  3.500000
...