Самый быстрый способ заполнить значения фрейма данных, используя .loc из другого мультииндексированного фрейма данных - PullRequest
0 голосов
/ 26 апреля 2018

у меня есть фрейм данных df1 :

key1    key2   val
1       100     
2       500   
4       400 

Также у меня есть мультииндексированный фрейм данных df2 :

       c
a  b     
1 100  a
2 200  b
3 300  j
4 400  e
5 500  t

iхочу заполнить столбец val моего df1 из многоиндексированного фрейма данных df2

Я попытался:

for index,row in df1.iterrows():
    try:
        data = df2.loc([row['key1'],row['key2'])
        df1.loc[(df1.key1 == row['key1']) & (df1.key2 == row['key2']), 'val'] = data
    except:
        pass

наконец, мой df1 должен выглядеть следующим образом:

key1    key2   val
1       100     a
2       500   
4       400     e

Но моя главная проблема в том, что фактическая длина df2 (многоиндексная df) будет составлять около 60-70 тысяч строк.

Длина df1 вряд ли будет 10 строк,(и я хочу повторить этот процесс, принимая df1, содержащий другие данные)

ТАК использует этот .loc для работы цикла?Это самый быстрый?

Или использование .apply будет быстрее?

Я хочу, чтобы эта итерация была самой быстрой.

Любые отведения на , выполняющие это самым быстрым способом

Ответы [ 2 ]

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

Я думаю, что это не fill value вопрос, а filter index вопрос.Попробуйте ниже:

df1 = df1.set_index(["key1", "key2"])
result = df2.loc[df1.index, :].reset_index()

Если вы хотите оставить исходные столбцы:

result.columns=["key1", "key2", "val"]
0 голосов
/ 26 апреля 2018

В пандах лучше избегать loops s - iterrows и apply (петли под капотом), лучше векторизованные решения.

Использовать join с параметром on:

#for improve performance sort index and columns
df2 = df2.sort_index()
df1 = df1.sort_values(['key1','key2'])

df = df1.join(df2, on=['key1','key2'])
print (df)
   key1  key2  val    c
0     1   100  NaN    a
1     2   500  NaN  NaN
2     4   400  NaN    e

РЕДАКТИРОВАТЬ:

Другой подход - объединение MultiIndex и столбцы значений и использование map:

df2.index = ['{}_{}'.format(a,b) for a, b in df2.index]
print (df2)
       c
1_100  a
2_200  b
3_300  j
4_400  e
5_500  t

df1['joined'] = df1['key1'].astype(str) + '_' + df1['key2'].astype(str)
print (df1)
   key1  key2  val joined
0     1   100  NaN  1_100
1     2   500  NaN  2_500
2     4   400  NaN  4_400

df1['col'] = df1['joined'].map(df2['c'])
print (df1)
   key1  key2  val joined  col
0     1   100  NaN  1_100    a
1     2   500  NaN  2_500  NaN
2     4   400  NaN  4_400    e

Сроки :

np.random.seed(123)
N = 100000
df2 = pd.DataFrame(np.random.randint(10000, size=(N, 3)), columns=list('abc'))
df2 = df2.drop_duplicates(['a','b']).set_index(['a','b'])
print (df2.head())
              c
a    b         
3582 1346  5218
7763 9785  7382
5857 96    6257
6782 4143  4169
5664 942   6368

df1 = df2.iloc[np.random.randint(N, size=10)].reset_index()
df1.columns = ['key1','key2','val']
print (df1)
   key1  key2   val
0  5157  9207   283
1  6452  6474  7092
2  1264  5009  5123
3    86  7225  1025
4  7787  5134   637
5  9406  6119  8719
6  7479  1493  1525
7  4098  7248  7618
8  9921  7925  8547
9  2320   764  1564

1.Присоединиться с несортированными MultiIndex, столбцы:

In [42]: %timeit df1.join(df2, on=['key1','key2'])
100 loops, best of 3: 11.1 ms per loop

2. Затем выполнить первую сортировку, а затем объединить (сортировка неиспользуется в таймингах):

df2 = df2.sort_index()

In [44]: %timeit df1.join(df2, on=['key1','key2'])
100 loops, best of 3: 10.5 ms per loop

3. map решение, также присоединение MultiIndex не учитывается в таймингах, если все те же данные выполняются только один раз:

df2.index = ['{}_{}'.format(a,b) for a, b in df2.index]
df1['joined'] = df1['key1'].astype(str) + '_' + df1['key2'].astype(str)

In [51]: %timeit df1['col'] = df1['joined'].map(df2['c'])
1000 loops, best of 3: 371 µs per loop

In [55]: %%timeit
    ...: df1['joined'] = df1['key1'].astype(str) + '_' + df1['key2'].astype(str)
    ...: df1['col'] = df1['joined'].map(df2['c'])
    ...: 
1000 loops, best of 3: 1.08 ms per loop
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...