我有一个数据框,其中的列包含重复的值,这是因为由于我想将跨多年的数据转换为仅具有唯一值。为此,我希望将其他列转换为字典,这些字典将以{'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']}
当我变成一个数据帧时,它会转换为
Resulting data frame which is not correct
虽然预期的输出是格式为
的数据帧有帮助吗?预先感谢。
答案 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
中使用字典是一种反模式。
让我们假设您想要每个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
答案 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'}
我希望它能解决您的问题