Python 熊猫数据帧的重新排列

Python 熊猫数据帧的重新排列,python,pandas,Python,Pandas,我有以下类型的数据帧 test = {0:['loc_a','loc_b','loc_c'],1:['new_list','new_list','change_list'],2:['abc','abc','abc'],3:['def','change_list','def'],4:['ghi','def','ghi'],5:['change_list','ghi','jkl'],6:['jkl','jkl','mno'],7:['mno','pqr','pqr']} test = pd.Data

我有以下类型的数据帧

test = {0:['loc_a','loc_b','loc_c'],1:['new_list','new_list','change_list'],2:['abc','abc','abc'],3:['def','change_list','def'],4:['ghi','def','ghi'],5:['change_list','ghi','jkl'],6:['jkl','jkl','mno'],7:['mno','pqr','pqr']}
test = pd.DataFrame(test)

我需要以以下形式处理数据帧

test2 = {'location':['loc_a','loc_a','loc_a','loc_a','loc_a'],'list_type':['new_list','new_list','new_list','change_list','change_list'],'value':['abc','def','ghi','jkl','mno']}
test2 = pd.DataFrame(test2)


真的需要帮助因为我被困在这里,是否可以通过处理每一行将数据转换为所需的数据帧形式?

IIUC,这并不是您想要在数据帧中首先使用的数据类型。如果您可以控制如何收集和存储这些数据,我可能会尝试在将其存储为表格格式之前进行一些预处理。我能想到的唯一解决方案是迭代行并存储新的输出,以便稍后转换为数据帧

data = []

for row in test.itertuples():
    loc = row[1]
    
    changelist_idx = row.index("change_list") + 1
    try:
        newlist_idx = row.index("new_list") + 1
    except ValueError:
        newlist_idx = changelist_idx
    
    newlist_values = row[newlist_idx:changelist_idx - 1]
    changelist_values = row[changelist_idx:]
    
    for value in newlist_values:
        data.append([loc, "new_list", value])
    for value in changelist_values:
        data.append([loc, "change_list", value])
    
out = pd.DataFrame(data, columns=["location", "list_type", "value"])
print(out)

   location    list_type value
0     loc_a     new_list   abc
1     loc_a     new_list   def
2     loc_a     new_list   ghi
3     loc_a  change_list   jkl
4     loc_a  change_list   mno
5     loc_b     new_list   abc
6     loc_b  change_list   def
7     loc_b  change_list   ghi
8     loc_b  change_list   jkl
9     loc_b  change_list   pqr
10    loc_c  change_list   abc
11    loc_c  change_list   def
12    loc_c  change_list   ghi
13    loc_c  change_list   jkl
14    loc_c  change_list   mno
15    loc_c  change_list   pqr

IIUC,这并不是你想要的数据帧中的数据类型。如果您可以控制如何收集和存储这些数据,我可能会尝试在将其存储为表格格式之前进行一些预处理。我能想到的唯一解决方案是迭代行并存储新的输出,以便稍后转换为数据帧

data = []

for row in test.itertuples():
    loc = row[1]
    
    changelist_idx = row.index("change_list") + 1
    try:
        newlist_idx = row.index("new_list") + 1
    except ValueError:
        newlist_idx = changelist_idx
    
    newlist_values = row[newlist_idx:changelist_idx - 1]
    changelist_values = row[changelist_idx:]
    
    for value in newlist_values:
        data.append([loc, "new_list", value])
    for value in changelist_values:
        data.append([loc, "change_list", value])
    
out = pd.DataFrame(data, columns=["location", "list_type", "value"])
print(out)

   location    list_type value
0     loc_a     new_list   abc
1     loc_a     new_list   def
2     loc_a     new_list   ghi
3     loc_a  change_list   jkl
4     loc_a  change_list   mno
5     loc_b     new_list   abc
6     loc_b  change_list   def
7     loc_b  change_list   ghi
8     loc_b  change_list   jkl
9     loc_b  change_list   pqr
10    loc_c  change_list   abc
11    loc_c  change_list   def
12    loc_c  change_list   ghi
13    loc_c  change_list   jkl
14    loc_c  change_list   mno
15    loc_c  change_list   pqr

数据需要一些重塑以获得所需的形式;首先,您需要
melt
,执行
groupby
(确保未对其排序,以便保留当前顺序):

我建议你独立地运行每一行,这样你就可以理解转换的每个阶段;你甚至可以想出一个更好的方法,甚至可以摆脱不必要的步骤:

(
    test.melt(0)
    .groupby(0, sort=False)["value"]
    .agg(",".join)
    .str.split(",")
    .explode()
    .rename_axis("location")
    .reset_index()
    .assign(list_type=lambda x: x.loc[x["value"].str.contains("list"), "value"])
    .ffill()
    .query("value!=list_type")
)



  location  value   list_type
1   loc_a   abc     new_list
2   loc_a   def     new_list
3   loc_a   ghi     new_list
5   loc_a   jkl     change_list
6   loc_a   mno     change_list
8   loc_b   abc     new_list
10  loc_b   def     change_list
11  loc_b   ghi     change_list
12  loc_b   jkl     change_list
13  loc_b   pqr     change_list
15  loc_c   abc     change_list
16  loc_c   def     change_list
17  loc_c   ghi     change_list
18  loc_c   jkl     change_list
19  loc_c   mno     change_list
20  loc_c   pqr     change_list

数据需要一些重塑以获得所需的形式;首先,您需要
melt
,执行
groupby
(确保未对其排序,以便保留当前顺序):

我建议你独立地运行每一行,这样你就可以理解转换的每个阶段;你甚至可以想出一个更好的方法,甚至可以摆脱不必要的步骤:

(
    test.melt(0)
    .groupby(0, sort=False)["value"]
    .agg(",".join)
    .str.split(",")
    .explode()
    .rename_axis("location")
    .reset_index()
    .assign(list_type=lambda x: x.loc[x["value"].str.contains("list"), "value"])
    .ffill()
    .query("value!=list_type")
)



  location  value   list_type
1   loc_a   abc     new_list
2   loc_a   def     new_list
3   loc_a   ghi     new_list
5   loc_a   jkl     change_list
6   loc_a   mno     change_list
8   loc_b   abc     new_list
10  loc_b   def     change_list
11  loc_b   ghi     change_list
12  loc_b   jkl     change_list
13  loc_b   pqr     change_list
15  loc_c   abc     change_list
16  loc_c   def     change_list
17  loc_c   ghi     change_list
18  loc_c   jkl     change_list
19  loc_c   mno     change_list
20  loc_c   pqr     change_list

下面是使用pandas
.iterrows()
的简单答案。我希望能供你参考

#收集要堆叠在列表中的项目。
test['lst']=test[范围(1,8)]。值。tolist()
df_all=pd.DataFrame()
#为每个位置创建所需的数据帧。
对于索引,test.iterrows()中的行:
loc=第[0]行
df_by_loc=pd.DataFrame()
对于第['lst']行中的lst:
df=pd.DataFrame({'location':[loc]})
#如果lst是“新建列表”或“更改列表”,请创建列表类型。
如果lst是“新列表”:
列表类型='新列表'
elif lst是“变更列表”:
列表类型='更改列表'
其他:
#在上述情况以外的情况下,实际创建了“列表类型”和“值”项。
df['list_type']=list_type
df['value']=lst
#通过concating为每个位置创建一个数据帧。
如果lst不在[“新列表”、“更改列表”]:
df_by_loc=pd.concat([df_by_loc,df],轴=0)
df_all=pd.concat([df_all,df_by_loc],轴=0)
结果如下

打印(df_all)
位置列表\u类型值
0查找新列表abc
0定位一个新的列表定义
0定位一个新的ghi列表
0位置a变更列表jkl
0位置\u变更\u列表mno
0位置b新列表abc
0位置b更改列表定义
0位置变更清单ghi
0位置b更改列表jkl
0位置变更清单pqr
0位置变更列表abc
0 loc_c更改列表定义
0位置变更清单ghi
0位置变更列表jkl
0位置变更列表mno
0位置变更清单pqr

下面是使用pandas
.iterrows()
的简单答案。我希望能供你参考

#收集要堆叠在列表中的项目。
test['lst']=test[范围(1,8)]。值。tolist()
df_all=pd.DataFrame()
#为每个位置创建所需的数据帧。
对于索引,test.iterrows()中的行:
loc=第[0]行
df_by_loc=pd.DataFrame()
对于第['lst']行中的lst:
df=pd.DataFrame({'location':[loc]})
#如果lst是“新建列表”或“更改列表”,请创建列表类型。
如果lst是“新列表”:
列表类型='新列表'
elif lst是“变更列表”:
列表类型='更改列表'
其他:
#在上述情况以外的情况下,实际创建了“列表类型”和“值”项。
df['list_type']=list_type
df['value']=lst
#通过concating为每个位置创建一个数据帧。
如果lst不在[“新列表”、“更改列表”]:
df_by_loc=pd.concat([df_by_loc,df],轴=0)
df_all=pd.concat([df_all,df_by_loc],轴=0)
结果如下

打印(df_all)
位置列表\u类型值
0查找新列表abc
0定位一个新的列表定义
0定位一个新的ghi列表
0位置a变更列表jkl
0位置\u变更\u列表mno
0位置b新列表abc
0位置b更改列表定义
0位置变更清单ghi
0位置b更改列表jkl
0位置变更清单pqr
0位置变更列表abc
0 loc_c更改列表定义
0位置变更清单ghi
0位置变更列表jkl
0位置变更列表mno
0位置变更清单pqr

你能画出你想做什么吗?将第2-7列中的字母移动到值列的过程是什么?我们无法帮助您将所有这些列移动到单个列,除非定义为什么每个字母都应该位于第一行的每个点,我们在第1列中有新的_列表值,它指示下一个3列(2、3和4)在更改列表值出现在第6列之前属于该类别,第6列之后的值属于更改列表,但是,由于值的数量增加或减少,下一行的新更改列表和更改列表的列位置可能不同,有点难以解释,但我希望你能理解我想表达的意思。你能画出你想做的吗?将第2-7列中的字母移动到值列的过程是什么?我们无法帮助您将所有这些列移动到s