DataFrame - групповой поиск уникальных значений - есть ли способ сделать это быстрее? - PullRequest
0 голосов
/ 15 марта 2019

Задача:
В кадре данных столбцов продукт, день, pgroup, цена (логический ключ = продукт, день) для некоторых строк столбец pgroup пуст.Если есть другие наборы данных для этого продукта, содержащие значение, его следует использовать для пустых наборов данных.

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

Пример:

Данные:

df = pd.DataFrame([['a','2018-02-03','G1',47],
              ['a','2018-02-04',None,25],
              ['a','2018-02-05','G1',10],
              ['a','2018-02-06',None,22],
              ['a','2018-02-07',None,84],
              ['b','2018-02-03',None,10],
              ['b','2018-02-04',None,21],
              ['b','2018-02-05',None,2],
              ['b','2018-02-06','G2',18],
              ['b','2018-02-07','G2',11],
              ['c','2018-02-03','G2',63],
              ['c','2018-02-04','G2',83],
              ['c','2018-02-05',None,20],
              ['c','2018-02-06',None,68],
              ['c','2018-02-07',None,33]])
df.columns = ['product','day','pgroup', 'value']

Код:

# Loop for each product
for xprod in df['product'].unique().tolist():
    # find unique values for pgroup
    unique_values = df[df['product'] == xprod]['pgroup'].unique()
    # Change Datatypes because of NaN-Values in Series
    unique_values_str = [str(i) for i in unique_values]
    # 2 values, first is NaN => take second 
    if len(unique_values_str) == 2 and (unique_values_str[0] == 'nan'):
        df.loc[df['product'] == xprod, 'pgroup'] = unique_values_str[1]
    # 2 values, second is NaN => take first
    elif len(unique_values_str) == 2 and (unique_values_str[1] == 'nan'):
        df.loc[df['product'] == xprod, 'pgroup'] = unique_values_str[0] 

Ожидаемый результат:

    product     day         pgroup  value
0   a           2018-02-03  G1      47
1   a           2018-02-04  G1      25
2   a           2018-02-05  G1      10
3   a           2018-02-06  G1      22
4   a           2018-02-07  G1      84
5   b           2018-02-03  G2      10
6   b           2018-02-04  G2      21
7   b           2018-02-05  G2      2
8   b           2018-02-06  G2      18
9   b           2018-02-07  G2      11
10  c           2018-02-03  G2      63
11  c           2018-02-04  G2      83
12  c           2018-02-05  G2      20
13  c           2018-02-06  G2      68
14  c           2018-02-07  G2      33

Аннотация:
По моим осмотрам деталикоторые занимают большую часть времени, это первые две строки:

 # Loop for each product
    for xprod in df['product'].unique().tolist():
        # find unique values for pgroup
        unique_values = df[df['product'] == xprod]['pgroup'].unique()

1 Ответ

1 голос
/ 16 марта 2019

Это кажется немного хакерским, и я действительно не знаю, как это будет работать, но я думаю, что это должно быть немного быстрее.

df2 = df
df2['pgroup'] = df.groupby(['product'])['pgroup'].transform(lambda x : repr(set(x) - set([None]) ).replace("{'",'').replace("'}",'') )

Возможно, вам также придется изменить порядок очистки строки, созданной из repr, если это вызовет какие-либо проблемы со значениями, которые может принимать pgroup.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...