Создание нового столбца данных dask с использованием значений из другого кадра данных приводит к ошибке «размеры фрагментов неизвестны» - PullRequest
1 голос
/ 01 апреля 2019

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

import pandas as pd
import numpy as np
import dask.dataframe as dd
holdings=pd.DataFrame({'cusip': ['abcd', 'efgh', 'ijkl'], 'date': ['1/1/2000', '1/1/2005', '1/1/2010']})
ratings=pd.DataFrame({'cusip':['abcd','efgh','efgh'],'date':['1/1/2001','1/1/2004','1/1/2006'],'rating':['A','AAA','B']}
dd.from_pandas(df1, npartitions=2)

Все даты имеют тип datetime.date. Цель состоит в том, чтобы для каждой строки в запасах новый столбец содержал индекс оценок, где строка содержит самую последнюю доступную оценку для клипа на дату в запасах. Например, вторая строка нового столбца в запасах должна содержать индекс, указывающий на вторую строку рейтингов.

Я написал следующий код, который делает то, что я ищу, когда авуары и рейтинги - это просто фреймы данных панд (не dask):

def get_rating_index(cusip,date,ratings):
    if cusip in ratings['cusip'].values:
        temp=ratings[ratings['cusip']==cusip]
        avail_ratings=temp[temp['date'].apply(lambda x: x<date)]
        if avail_ratings.shape[0]>0:
            final=avail_ratings[avail_ratings['date']==max(avail_ratings['date'].values)]
            return final.index[0]
        else:
            return np.nan
    else:
        return np.nan
holdings['ratings_match']=pd.Series(get_rating_index(holdings['cusip'][i],holdings['date'][i],ratings) for i in holdings.index)

Этот пост был полезен для более простой функции, которую мне нужно было применить к этим же данным, но когда я попытался использовать ее для этой задачи, я получил ошибку: «Размеры блоков массива неизвестны: % s ', (nan,),' произошло с индексом 0 ".

Это был точный код, который я использовал с dask (небольшое изменение по сравнению с функцией, которую я использовал с пандами):

def get_rating_index(row):
    if row['cusip'] in ratings['cusip'].values:
        temp=ratings[ratings['cusip']==row['cusip']]
        avail_ratings=temp[temp['date'].apply(lambda x: x<row['date'])]
        if avail_ratings.shape[0]>0:
            final=avail_ratings[avail_ratings['date']==max(avail_ratings['date'].values)]
            return final.index[0]
        else:
            return -1
    else:
        return -1

holdings['ratings_match'] = holdings.apply(get_rating_index,meta='int', axis=1)

Есть идеи о том, как сделать это без получения этой ошибки? Я должен отметить, что ошибка возникает один раз, когда я пытаюсь просмотреть данные (например, с holdings.head()), а не сразу, когда я создаю столбец.

1 Ответ

0 голосов
/ 01 апреля 2019

Это еще не полный ответ, но может помочь вам начать:

holdings.apply(get_rating_index, meta='int', axis=1)

Это крайне вероятно , что вы действительно хотите map или map_partition здесь.Они позволяют вам обобщать из панд гораздо более простым способом, и, как правило, гораздо более эффективны.

Действительно, функция, которую вы запускаете, get_rating_index очень похожа на отдельную карту или операцию, хотя трудно сказать, какова цель.С другой стороны, temp=ratings[ratings['cusip']==row['cusip']] выглядит как групповая операция.

...