обновление столбцов во вложенных циклах в python - PullRequest
0 голосов
/ 06 января 2020

У меня есть два кадра данных A и B следующим образом:

A
col1 col2 col3
A     B    V1
A     B    V2
A     C    V1
A     E    V2

B
Col1 Col2 Value1 Value2
A     B   nan     nan
A     D   nan     nan
A     C   nan     nan
A     G   nan     nan
A     E   nan     nan

Я хочу обновить столбцы Value1 и Value2 в кадре данных B на основе данных A, как если бы комбинация Col1 и Col 2 A существует в B, он обновит столбцы Value1 Value2, то есть значения из col3 в кадре данных A.

Я хочу вывод как:

Col1 Col2 Value1 Value2
A     B   V1      V2
A     D   nan     nan
A     C   V1      nan
A     G   nan     nan
A     E   nan     V2

Я пробовал следующий код в python :

def update_b():
for x in b.index:
    for y in a.index:          

            if ((a["col1"][y] == b["col1"][x]) & (a["col2"][y] == b["col2"][x])):

                if (a["col3"][y] == "V1"):
                    b["value1"][x] = "V1"
                else:
                    b["value2"][x] = "V2"

update_b ()

, но выдает ошибку

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Ответы [ 3 ]

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

Ваш фрейм (ы) имеет плохой дизайн, вы должны вернуться к ним, но чтобы ответить на ваш первоначальный вопрос, мы можем использовать мультииндекс и карту

s = df.groupby(['col1','col2'])['col3'].agg(','.join).to_dict()
df2['Val'] = df2.set_index(['Col1','Col2']).index.map(s)
df2.loc[df2['Val'].str.contains(r'(v1)',case=False)==True,'Value1'] = 'V1'
df2.loc[df2['Val'].str.contains(r'(v2)',case=False)==True,'Value2'] = 'V2'
df2.pop('Val')

Результат:

print(df2)
   Col1 Col2 Value1 Value2
0    A    B     V1     V2
1    A    D    NaN    NaN
2    A    C     V1    NaN
3    A    G    NaN    NaN
4    A    E    NaN     V2
1 голос
/ 06 января 2020

Насколько я понял логи c, вы можете попробовать следующую функцию: Обратите внимание, последняя строка отличается от вашего ожидаемого результата (я не могу понять, как это возможно).

def return_updated_B(df):
    m=A.rename(columns=lambda x:x.capitalize()) #capitalize cols of A
    n=m.set_index(['Col1','Col2',m.groupby(['Col1','Col2'])
           .cumcount().add(1)]).unstack().droplevel(0,axis=1).add_prefix('Value')
    return n.reindex(pd.MultiIndex.from_arrays((B['Col1'],B['Col2']))).reset_index()

print(return_updated_B(A))

  Col1 Col2 Value1 Value2
0    A    B     V1     V2
1    A    D    NaN    NaN
2    A    C     V1    NaN
3    A    G    NaN    NaN
4    A    E     V2    NaN
0 голосов
/ 06 января 2020

Вы можете попробовать перебрать строки первого кадра данных и loc строк второго для получения значений.

Что-то вроде следующего:

for index, row in dfA.iterrows():
    dfB.loc[dfB.Col1 == row['col1'] & dfB.Col2 == row['col2'], "Value1"] = row['value1'] 

Запись ответа из памяти поэтому могут быть некоторые синтаксические ошибки.

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