Эффективный способ поиска столбца данных Pandas - PullRequest
0 голосов
/ 31 октября 2019

У меня есть следующий фрейм данных:

+-------------------------------------------+----------------------------------------+----------------+----------------------------------+
|                  Lookup                   |             LookUp Value 1             | LookUp Value 2 |          LookUp Value 3          |
+-------------------------------------------+----------------------------------------+----------------+----------------------------------+
| 300000,50000,500000,100000,1000000,200000 | -1820,-1820,-1820,-1820,-1820,-1820    |    1,1,1,1,1,1 |    1820,1820,1820,1820,1820,1820 |
| 100000,1000000,200000,300000,50000,500000 | -1360,-28760,-1360,-28760,-1360,-28760 |    2,3,2,3,2,3 | 4120,31520,4120,31520,4120,31520 |
+-------------------------------------------+----------------------------------------+----------------+----------------------------------+

Каждый столбец - это список, первые столбцы - это ключ поиска, а остальные - это значение поиска. Я хотел бы сгенерировать кадр данных следующим образом.

+--------------------+--------------------+--------------------+
| Lookup_300K_Value1 | Lookup_300K_Value2 | Lookup_300K_Value3 |
+--------------------+--------------------+--------------------+
|              -1820 |                  1 |               1820 |
|             -28760 |                  3 |              31520 |
+--------------------+--------------------+--------------------+

На самом деле у меня есть решение, использующее pandas.apply и обрабатывающее строку за строкой. Это очень очень медленно, поэтому я хотел бы посмотреть, есть ли какое-нибудь решение, которое может ускорить процесс? Большое спасибо.

РЕДАКТИРОВАТЬ: я добавил код генерации данных ниже

d = {'Lookup_Key': ['300000,50000,500000,100000,1000000,200000', '100000,1000000,200000,300000,50000,500000'],
     'LookUp_Value_1': ['-1820,-1820,-1820,-1820,-1820,-1820', '-1360,-28760,-1360,-28760,-1360,-28760'],
     'LookUp_Value_2': ['1,1,1,1,1,1', '2,3,2,3,2,3'],
     'LookUp_Value_3': ['1820,1820,1820,1820,1820,1820', '4120,31520,4120,31520,4120,31520']}
df = pd.DataFrame(data=d)

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Решение протестировано с отсутствующими значениями в некоторых столбцах, но в Lookup нет ни NaN, ни Nones:

df = pd.concat([df[x].str.split(',', expand=True).stack() for x in df.columns], axis=1, keys=df.columns)
df = df.reset_index(level=1, drop=True).set_index('Lookup', append=True).unstack().sort_index(axis=1, level=1)
df.columns = [f'{b}_{a}' for a, b in df.columns]

Идея состоит в том, чтобы разбить каждое значение в цикле, разбить на ряд и объединить вместе,последнее изменение на stack:

df = pd.concat([df[x].str.split(',').explode() for x in df.columns], axis=1)
df = df.set_index('Lookup', append=True).unstack().sort_index(axis=1, level=1)
df.columns = [f'{b}_{a}' for a, b in df.columns]
print (df)
  100000_LookUp Value 1 100000_LookUp Value 2 100000_LookUp Value 3  \
0                 -1820                     1                  1820   
1                 -1360                     2                  4120   

  1000000_LookUp Value 1 1000000_LookUp Value 2 1000000_LookUp Value 3  \
0                  -1820                      1                   1820   
1                 -28760                      3                  31520   

  200000_LookUp Value 1 200000_LookUp Value 2 200000_LookUp Value 3  \
0                 -1820                     1                  1820   
1                 -1360                     2                  4120   

  300000_LookUp Value 1 300000_LookUp Value 2 300000_LookUp Value 3  \
0                 -1820                     1                  1820   
1                -28760                     3                 31520   

  50000_LookUp Value 1 50000_LookUp Value 2 50000_LookUp Value 3  \
0                -1820                    1                 1820   
1                -1360                    2                 4120   

  500000_LookUp Value 1 500000_LookUp Value 2 500000_LookUp Value 3  
0                 -1820                     1                  1820  
1                -28760                     3                 31520  
1 голос
/ 31 октября 2019

По сути, вы можете очень хорошо использовать groupby для достижения своей цели:

grouped = df.groupby("Lookup")

Теперь это объект типа dict, в котором есть значения, которые вы хотите получить для каждого значения Lookup в отдельных фреймах данных,Вопрос сейчас в том, как нам снова собрать все вместе, и здесь я должен прибегнуть к довольно хакерскому методу. Я уверен, что есть лучшие, но этот действительно дает хороший результат.

dflist = []
keylist = []
basecols = df.columns[1:]

for key, df in grouped.__iter__():
    keylist.append(key)
    dflist.append(df[basecols].reset_index(drop=True)

result = pd.concat(dflist, axis=1)
resultcolumns = pd.MultiIndex.from_product([keylist, basecols])
result.columns = resultcolumns

Это создает мультииндексированный DataFrame с результатом, который вы описали.

Выход:

>> result
   50000                 100000                200000                300000                500000                1000000
   Value1 Value2 Value3  Value1 Value2 Value3  Value1 Value2 Value3  Value1 Value2 Value3  Value1 Value2 Value3  Value1 Value2 Value3
0   -1820      1   1820   -1820      1   1820   -1820      1   1820   -1820      1   1820   -1820      1   1820   -1820      1   1820
1   -1360      2   4120   -1360      2   4120   -1360      2   4120  -28760      3  31520  -28760      3  31520  -28760      3  31520
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...