Хранение словарей внутри фрейма данных, которые имеют повторяющиеся записи в столбце уникальных значений - PullRequest
2 голосов
/ 09 июля 2019

У меня есть фрейм данных со столбцом, включающим повторяющиеся значения из-за наличия данных за несколько лет, которые я хочу преобразовать в наличие только уникальных значений.Для этого я хочу, чтобы другие столбцы были преобразованы в словари, в которых данные всех лет показывались бы в виде пар ключ-значение в формате {'year': value}.Это должно быть сделано для всех других столбцов, кроме столбца с уникальными значениями.Мой фрейм входных данных выглядит следующим образом:

Оригинальный фрейм входных данных

Воспроизводимый код для фрейма данных

df = pd.DataFrame({
    'A': {0: 'a1', 1: 'a2', 2: 'a3', 3: 'a4'}, 
    'Unique': {0: 'b1', 1: 'b1', 2: 'b2', 3: 'b2'}, 
    'Year': {0: 2017, 1: 2008, 2: 2017, 3: 2008} , 
    'C': {0: 'c1', 1: 'c2', 2: 'c3', 3: 'c4'}
})

До сих пор я пытался получитькомбинации значений в год для каждой переменной в списках и добавления ее в словарь в надежде преобразовать ее обратно во фрейм данных.Но это не позволит мне получить тот же результат, что и ожидаемый результат.

Пример того, что я сделал до сих пор:

B_list = list(df["Unique"])
temp_dict = {}
new_dict = {}
for a in set(Unique_list):
    i = 0
    new_dict[a] = {}
    temp_list = []
    for index, row in df.iterrows():
        if df["Unique"][i] == a:      
            temp_list.append(str(df["Year"][i]) +": " +  df["A"][i])
            i = i+1
        new_dict[a] = temp_list

. Он дает выходной словарь как

{'b1': ['2017: a1', '2008: a2'], 
 'b2': ['2017: a3', '2008: a4']}

, который, когда я превращаюсь во фрейм данных, преобразуется в

Результирующий кадр данных, который не является правильным

В то время как ожидаемый вывод - это кадр данных в формате

Ожидаемый выходной кадр данных

Любая помощь?Заранее спасибо.

Ответы [ 3 ]

2 голосов
/ 09 июля 2019

Для повышения производительности, если большие данные лучше не использовать словари в столбцах, но если маленькие данные, это возможно с помощью GroupBy.apply с пользовательской функцией:

def f(x):
    y = x.pop('Year')
    c = x.columns.difference(['Unique'])
    return pd.concat([pd.Series([dict(zip(y, x[col]))]).rename(col) for col in c], 1)

df1 = (df.groupby('Unique')
         .apply(f)
         .reset_index(level=1, drop=True)
         .rename_axis('B')
         .reset_index()
         .sort_index(axis=1))
print (df1)
                          A   B                         C
0  {2017: 'a1', 2008: 'a2'}  b1  {2017: 'c1', 2008: 'c2'}
1  {2017: 'a3', 2008: 'a4'}  b2  {2017: 'c3', 2008: 'c4'}

Лучшее решение - создать MultiIndex в столбцах:

df1 = df.set_index(['Unique','Year']).unstack()
print (df1)
          A         C     
Year   2008 2017 2008 2017
Unique                    
b1       a2   a1   c2   c1
b2       a4   a3   c4   c3

Или в индексе это зависит от того, что нужно окончательно:

df2 = df.set_index(['Unique','Year'])
print (df2)
              A   C
Unique Year        
b1     2017  a1  c1
       2008  a2  c2
b2     2017  a3  c3
       2008  a4  c4
0 голосов
/ 09 июля 2019

Попробуйте использовать apply и zip, чтобы сделать это

df = pd.DataFrame( {'A': {0: 'a1', 1: 'a2', 2: 'a3', 3: 'a4'},
                    'Unique': {0: 'b1', 1: 'b1', 2: 'b2', 3: 'b2'},
                    'Year': {0: 2017, 1: 2008, 2: 2017, 3: 2008} ,
                    'C': {0: 'c1', 1: 'c2', 2: 'c3', 3: 'c4'}})

def converting_into_dict(grp,col_name,key="Year"):
    return dict(zip(grp[key], grp[col_name]))

res = pd.DataFrame(df.groupby('Unique').apply(lambda x :converting_into_dict(x,"A")),columns=["A"])
res2 = pd.DataFrame(df.groupby('Unique').apply(lambda x :converting_into_dict(x,"C")),columns=["B"])
final_res = pd.merge(res,res2,on=['Unique']).reset_index()
print(final_res)
      Unique         A                         B
0     b1  {2017: 'a1', 2008: 'a2'}  {2017: 'c1', 2008: 'c2'}
1     b2  {2017: 'a3', 2008: 'a4'}  {2017: 'c3', 2008: 'c4'}

Я надеюсь, что это решит вашу проблему

0 голосов
/ 09 июля 2019

Использование словарей в pandas DataFrame является своего рода антипаттерном.

Допустим, вы хотите, чтобы ваш результат получился для каждого уникального Unique значения A и Year.

Начнем с вашего DataFrame:

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

df = pd.DataFrame({
    'A': ['a1', 'a2', 'a3', 'a4'], 
    'Unique': ['b1', 'b1', 'b2', 'b2'], 
    'Year': [2017, 2008, 2017, 2008], 
    'C': ['c1', 'c2', 'c3', 'c4']
})

Теперь вы можете выбрать свои данные, указав b в качестве индекса.

df.set_index('Unique', drop=False, inplace=True)

С этим вы можете сделать:

In : df2.loc['b1']                                                           
Out: 
         A Unique  Year   C
Unique                     
b1      a1     b1  2017  c1
b1      a2     b1  2008  c2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...