Я новичок в Dask и ищу способ выравнивания столбца словаря в кадре данных PANDAS. Вот снимок экрана с первой строкой 16-миллионного ряда данных:
А вот пример текста из трех строк:
{{u'F9_07_PZ_COMP_DIRECT': u'0', u'F9_07_PZ_DIRTRSTKEY_NAME': u'DEBRA MEALY', u'F9_07_PZ_COMP_OTHER': u'0', u'F9_07_PZ_COMP_RELATED': u'0', u'F9_07_PZ_TITLE': u'CHAIR PERSON', u'F9_07_PZ_AVE_HOURS_WEEK': u'1.00', u'F9_07_PC_TRUSTEE_INDIVIDUAL': u'X'}, {u'F9_07_PZ_COMP_DIRECT': u'0', u'F9_07_PZ_DIRTRSTKEY_NAME': u'HELEN GORDON', u'F9_07_PZ_COMP_OTHER': u'0', u'F9_07_PZ_COMP_RELATED': u'0', u'F9_07_PZ_TITLE': u'VICE CHAIR', u'F9_07_PZ_AVE_HOURS_WEEK': u'1.00', u'F9_07_PC_TRUSTEE_INDIVIDUAL': u'X'}, {'F9_07_PC_HIGH_COMP_EMPLOYEE': 'X', 'F9_07_PZ_DIRTRSTKEY_NAME': 'ROB S KHANUJA', 'F9_07_PZ_COMP_OTHER': '14902', 'F9_07_PZ_COMP_RELATED': '0', 'F9_07_PZ_TITLE': 'EXEC. DIR. OPERATIONS', 'F9_07_PZ_AVE_HOURS_WEEK': '40.00', 'F9_07_PZ_COMP_DIRECT': '133173'}}
Обычно я выравниваю столбец Form990PartVIISectionAGrp со следующим кодом:
df = pd.concat([df.drop(['Form990PartVIISectionAGrp'], axis=1), df['Form990PartVIISectionAGrp'].swifter.apply(pd.Series)], axis=1)
Я пытаюсь сделать это в Dask, но получаю следующую ошибку: «ValueError: Столбцы в вычисленных данных не соответствуют столбцам в предоставленных метаданных.»
Я использую Python 2.7. Я импортирую соответствующие пакеты
from dask import dataframe as dd
from dask.multiprocessing import get
from multiprocessing import cpu_count
nCores = cpu_count()
Для проверки кода я создал случайную выборку данных:
dfs = df.sample(1000)
А затем сгенерируйте кадр данных Dask:
ddf = dd.from_pandas(dfs, npartitions=nCores)
В данный момент столбец имеет строковый формат, поэтому я преобразую его в словарь. Обычно я бы написал одну строчку кода:
dfs['Form990PartVIISectionAGrp'] = dfs['Form990PartVIISectionAGrp'].apply(literal_eval)
Но вместо этого я попытался сделать это здесь в более «похожей на Даск» форме, поэтому я пишу следующую функцию и затем применяю ее:
def make_dict(dfs):
dfs['Form990PartVIISectionAGrp'] = dfs['Form990PartVIISectionAGrp'].apply(literal_eval)
return dfs
ddf_out = ddf.map_partitions(make_dict, meta=dfs[:0]).compute()
Это работает - он возвращает фрейм данных PANDAS, в котором столбец Form990PartVIISectionAGrp представлен в формате словаря (однако, он работает не быстрее, чем не-Dask).
Затем я воссоздаю Dask DF:
ddf = dd.from_pandas(ddf_out, npartitions=nCores)
И напишите функцию для выравнивания столбца:
def flatten(ddf_out):
ddf_out = pd.concat([ddf_out.drop(['Form990PartVIISectionAGrp'], axis=1), ddf_out['Form990PartVIISectionAGrp'].apply(pd.Series)], axis=1)
#ddf_out = ddf_out['Form990PartVIISectionAGrp'].apply(pd.Series)
return ddf_out
Если я запусту этот код:
result = ddf.map_partitions(flatten)
Я получаю следующий вывод, где столбец не был сплющен:
Я также получал ошибки об отсутствующих метаданных, и, учитывая, что вышеупомянутое не помогло разобрать столбец словаря, поэтому я создал список столбцов, полученных простым выравниванием столбцов Python, и использовал его для создания словаря столбцов и типов данных:
metadir = {u'BusinessName': 'O', u'F9_07_PC_FORMER': 'O', u'F9_07_PC_HIGH_COMP_EMPLOYEE': 'O',
u'F9_07_PC_KEY_EMPLOYEE': 'O', u'F9_07_PC_OFFICER': 'O',
u'F9_07_PC_TRUSTEE_INDIVIDUAL': 'O', u'F9_07_PC_TRUSTEE_INSTITUTIONAL': 'O',
u'F9_07_PZ_AVE_HOURS_WEEK': 'O', u'F9_07_PZ_AVE_HOURS_WEEK_RELATED': 'O',
u'F9_07_PZ_COMP_DIRECT': 'O', u'F9_07_PZ_COMP_OTHER': 'O',
u'F9_07_PZ_COMP_RELATED': 'O', u'F9_07_PZ_DIRTRSTKEY_NAME': 'O',
u'F9_07_PZ_TITLE': 'O', u'NameBusiness': 'O', u'URL': 'O'}
Затем я применяю функцию выравнивания с этими метаданными:
result = ddf.map_partitions(flatten, meta=metadir)
В результате я получаю следующий вывод:
Запуск result.columns дает следующее:
Где это не удается, - это выполнение compute (), где я получаю следующее сообщение об ошибке: «ValueError: Столбцы в вычисленных данных не совпадают со столбцами в предоставленных метаданных». Я получаю ту же ошибку, пишу ли я:
result.compute()
или
result.compute(meta=metadir)
Я не уверен, что я здесь делаю неправильно. Столбцы в result , похоже, совпадают с столбцами в metadir . Любые предложения будут с благодарностью.
UPDATE:
Вот мой пример обновления функции сглаживания.
meta = pd.DataFrame(columns=['URL', 'F9_07_PC_TRUSTEE_INDIVIDUAL',
'F9_07_PZ_DIRTRSTKEY_NAME',
'F9_07_PZ_COMP_OTHER',
'F9_07_PZ_COMP_RELATED',
'F9_07_PZ_TITLE',
'F9_07_PZ_AVE_HOURS_WEEK',
'F9_07_PZ_COMP_DIRECT',
'F9_07_PZ_AVE_HOURS_WEEK_RELATED',
'F9_07_PC_OFFICER',
'F9_07_PC_HIGH_COMP_EMPLOYEE',
'BusinessName',
'F9_07_PC_KEY_EMPLOYEE',
'F9_07_PC_TRUSTEE_INSTITUTIONAL',
'NameBusiness',
'F9_07_PC_FORMER'], dtype="O")
def flatten(ddf_out):
ddf_out = pd.concat([df.drop(['Form990PartVIISectionAGrp'], axis=1), df['Form990PartVIISectionAGrp'].apply(pd.Series)], axis=1)
for m in meta:
if m not in ddf_out:
df[m] = ''
return ddf_out
Тогда я бегу:
result = ddf.map_partitions(flatten, meta=meta).compute()