Возврат фрагментов строк из отдельных фреймов данных pandas на основе мультиусловной логики - PullRequest
0 голосов
/ 25 апреля 2018

Я новичок в Python и пытаюсь поработать с кадрами данных в пандах

С левой стороны находится фрагмент первичного информационного кадра (df1), а с правой стороны - второй (df2). Цель состоит в том, чтобы заполнить столбец df1 ['vd_type'] строками, основанными на нескольких частях условной логики. Я могу заставить эту работу работать с вложенными функциями np.where (), но по мере того, как это углубляется в иерархию, оно становится слишком длинным для запуска вообще, поэтому я ищу более элегантное решение.

Английская версия логики такова: Для df1 ['vd_type']: если df1 ['shape'] == первые два символа в df2 ['vd_combo'] И df1 ['vd_pct'] <= df2 ['combo_value'], то верните последние 3 символа в df2 ['vd_combo'] на строке, где оба эти условия выполняются. Если он не может найти строку в df2, где оба условия выполняются, вернуть «vd4». </p>

Заранее спасибо!


РЕДАКТИРОВАТЬ # 2: Итак, я хочу реализовать третье условие, основанное на другой переменной, со всем тем же, за исключением того, что в df1 есть еще один столбец 'log_vsc' с существующими значениями, и цель состоит в том, чтобы заполнить пустой df1 столбец vsc_type с одной из 4 строк в той же схеме. Дополнительным условием было бы просто то, что 'vd_type', который мы только что определили, будет соответствовать столбцу 'vd', возникающему в результате разделения 'vsc_combo'.

df3 = pd.DataFrame()
df3['vsc_combo'] = ['A1_vd1_vsc1','A1_vd1_vsc2','A1_vd1_vsc3','A1_vd2_vsc1','A1_vd2_vsc2' etc etc etc
df3['combo_value'] = [(number), (number), (number), (number), (number), etc etc

df3[['shape','vd','vsc']] = df3['vsc_combo'].str.split('_', expand = True)

def vsc_condition( row, df3):
    df_select = df3[(df3['shape'] == row['shape']) & (df3['vd'] == row['vd_type']) & (row['log_vsc'] <= df3['combo_value'])]
    if df_select.empty:
        return 'vsc4'
    else:
        return df_select['vsc'].iloc[0]

## apply vsc_type
df1['vsc_type'] = df1.apply( vsc_condition, args = ([df3]), axis = 1)

И это работает !! Еще раз спасибо!

1 Ответ

0 голосов
/ 25 апреля 2018

так что ваши входы похожи на:

import pandas as pd
df1 = pd.DataFrame({'shape': ['A2', 'A1', 'B1', 'B1', 'A2'],
                    'vd_pct': [0.78, 0.33, 0.48, 0.38, 0.59]} )
df2 = pd.DataFrame({'vd_combo': ['A1_vd1', 'A1_vd2', 'A1_vd3', 'A2_vd1', 'A2_vd2', 'A2_vd3', 'B1_vd1', 'B1_vd2', 'B1_vd3'],
                    'combo_value':[0.38, 0.56, 0.68, 0.42, 0.58, 0.71, 0.39, 0.57, 0.69]} )

Если вы не против создания столбцов в df2 (вы можете удалить их в конце, если это проблема), вы генерируете два столбца shape и vd, разделяя столбец vd_combo:

df2[['shape','vd']] = df2['vd_combo'].str.split('_',expand=True)

Затем вы можете создать функцию condition, которую вы будете использовать в apply, такую ​​как:

def condition( row, df2):
   # row will be a row of df1 in apply
   # here you select only the rows of df2 with your conditions on shape and value
   df_select = df2[(df2['shape'] == row['shape']) & (row['vd_pct'] <= df2['combo_value'])]
   # if empty (your condition not met) then return vd4
   if df_select.empty:
       return 'vd4'
   # if your condition met, then return the value of 'vd' the smallest
   else:
       return df_select['vd'].iloc[0]

Теперь вы можете создать свой столбец vd_type в df1 с помощью:

df1['vd_type'] = df1.apply( condition, args =([df2]), axis=1)

df1 это как:

  shape  vd_pct vd_type
0    A2    0.78     vd4
1    A1    0.33     vd1
2    B1    0.48     vd2
3    B1    0.38     vd1
4    A2    0.59     vd3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...