Обновление нескольких столбцов одновременно с помощью iloc - PullRequest
0 голосов
/ 14 мая 2019

Как я могу обновить несколько столбцов строки более оптимизированным способом?

masks_df.iloc[mask_row.Index, shelf_number_idx] = tags_on_mask['shelf_number'].iloc[0]
masks_df.iloc[mask_row.Index, stacking_layer_idx] = tags_on_mask['stacking_layer'].iloc[0]
masks_df.iloc[mask_row.Index, facing_sequence_number_idx] = tags_on_mask['facing_sequence_number'].iloc[0]

Спасибо.

1 Ответ

2 голосов
/ 14 мая 2019

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

tags_on_mask = pd.DataFrame({
        'A':list('ab'),
         'facing_sequence_number':[30,5],
         'stacking_layer':[70,8],
         'col_2':[5,7],
         'shelf_number':[50,3],
})

print (tags_on_mask)
   A  facing_sequence_number  stacking_layer  col_2  shelf_number
0  a                      30              70      5            50
1  b                       5               8      7             3

np.random.seed(100)
masks_df = pd.DataFrame(np.random.randint(10, size=(5,5)), columns=tags_on_mask.columns)
print (masks_df)
   A  facing_sequence_number  stacking_layer  col_2  shelf_number
0  8                       8               3      7             7
1  0                       4               2      5             2
2  2                       2               1      0             8
3  4                       0               9      6             2
4  4                       1               5      3             4

shelf_number_idx = 1
stacking_layer_idx = 2
facing_sequence_number_idx = 3

pos = [shelf_number_idx, stacking_layer_idx, facing_sequence_number_idx]
cols = ['shelf_number','stacking_layer','facing_sequence_number']

Вы можете передать список в функцию iloc и преобразовать первые значения столбца в массив numpy с помощью select first, но производительность не увеличивается (только лучшечитаемый код на мой взгляд):

masks_df.iloc[3, pos] = tags_on_mask[cols].values[0, :]

Для повышения производительности возможно использование DataFrame.iat:

masks_df.iat[2, shelf_number_idx] = tags_on_mask['shelf_number'].values[0]
masks_df.iat[2, stacking_layer_idx] = tags_on_mask['stacking_layer'].values[0]
masks_df.iat[2, facing_sequence_number_idx] = tags_on_mask['facing_sequence_number'].values[0]

Или:

for i, c in zip(pos, cols):
    masks_df.iat[2, i] = tags_on_mask[c].values[0]

print (masks_df)
   A  facing_sequence_number  stacking_layer  col_2  shelf_number
0  8                       8               3      7             7
1  0                       4               2      5             2
2  2                      50              70     30             8
3  4                      50              70     30             2
4  4                       1               5      3             4

In [97]: %%timeit
    ...: pos = [shelf_number_idx, stacking_layer_idx, facing_sequence_number_idx]
    ...: cols = ['shelf_number','stacking_layer','facing_sequence_number']
    ...: vals = tags_on_mask[cols].values[0, :]
    ...: masks_df.iloc[3, pos] = vals
    ...: 
2.34 ms ± 33.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [98]: %%timeit
    ...: masks_df.iat[2, shelf_number_idx] = tags_on_mask['shelf_number'].values[0]
    ...: masks_df.iat[2, stacking_layer_idx] = tags_on_mask['stacking_layer'].values[0]
    ...: masks_df.iat[2, facing_sequence_number_idx] = tags_on_mask['facing_sequence_number'].values[0]
    ...: 
34.1 µs ± 1.99 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [100]: %%timeit
     ...: for i, c in zip(pos, cols):
     ...:     masks_df.iat[2, i] = tags_on_mask[c].values[0]
     ...: 
33.1 µs ± 250 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...