在具有唯一值列中重复条目的数据框中存储字典

时间:2019-07-09 10:27:40

标签: python pandas dataframe dictionary

我有一个数据框,其中的列包含重复的值,这是因为由于我想将跨多年的数据转换为仅具有唯一值。为此,我希望将其他列转换为字典,这些字典将以{'year':value}格式将所有年份的数据显示为键值对。必须对所有其他列执行此操作,但具有唯一值的列除外。 我的输入数据框如下所示

Original input data frame

数据帧的可复制代码

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']}

当我变成一个数据帧时,它会转换为

Resulting data frame which is not correct

虽然预期的输出是格式为

的数据帧

Expected output data frame

有帮助吗?预先感谢。

3 个答案:

答案 0 :(得分:2)

为了提高性能,如果较大的数据更好,而不是在列中使用字典,但是如果较小的数据可以通过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

答案 1 :(得分:0)

pandas DataFrame中使用字典是一种反模式。

让我们假设您想要每个UniqueA的唯一值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

答案 2 :(得分:0)

尝试使用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'}

我希望它能解决您的问题