我正在处理一些家庭数据,其中包含有关照料者和所照顾孩子人数的记录。当前,照料者记录中包含照料者和照料者所有孩子的人口统计信息。我想获取儿童的人口统计信息,并将其放入儿童各自的记录/行中。这是我正在使用的数据的示例:
Vis POS FAMID G1ID G2ID G1B G2B1 G2B2 G2B3 G1R G2R1 G2R2 G2R3
1 0 1 100011 1979 2010 White White
1 1 1 200011
1 0 2 100021 1969 2011 2009 AA AA White
1 1 2 200021
1 2 2 200022
1 0 3 100031 1966 2008 2010 2011 White White AA AA
1 1 3 200031
1 2 3 200032
1 3 3 200033
G1 =照顾者数据
G2 =子数据
GxBx =出生年份
GxRx =种族
Visit POS FAMID G1 G2 G1Birth G2Birth G1Race G2Race
1 0 1 100011 1979 White
1 1 1 200011 2010 White
1 0 2 100021 1969 AA
1 1 2 200021 2011 AA
1 2 2 200022 2009 White
1 0 3 100031 1966 White
1 1 3 200031 2008 White
1 2 3 200032 2010 AA
1 3 3 200033 2011 AA
从这两个表中,您可以看到我希望所有G2Bx列都属于一个新的G2Birth列,并且G2Rx列的原理相同。 (我的实际数据中实际上还有另外几个实例,例如种族和出生年份)
我一直在研究pandas数据框中的数据透视和堆栈功能,但是我没有得到想要的东西。我得到的最接近的是使用melt函数,但是与melt函数有关的问题是我无法将其映射到索引而没有从该列中获取所有值。 IE希望为仅拥有child1的人为child2和child3创建一行。我可能只是错误地使用了melt函数。
我想要的是当POS = 1时从g2Birthdate1映射到POS的所有值,以及所有g2Birthdate2到POS = 2索引的映射,等等。是否有一个函数可以帮助完成此任务?还是需要其他一些编码解决方案?
答案 0 :(得分:1)
您可以使用行和列MultiIndex以及左连接来完成此操作:
# df is your initial dataframe
# Make a baseline dataframe to hold the IDs
id_df = df.drop(columns=[c for c in df.columns if c not in ["G1ID", "G2ID","Vis","FAMID","POS"]])
# Make a rows MultiIndex to join on at the end
id_df = id_df.set_index(["Vis","FAMID","POS"])
# Rename the columns to reflect the hierarchical nature
data_df = df.drop(columns=[c for c in df.columns if c in ["G1ID", "G2ID", "POS"]])
# Make the first two parts of the MultiIndex required for the join at the end
data_df = data_df.set_index(["Vis","FAMID"])
# Make the columns also have a MultiIndex
data_df.columns = pd.MultiIndex.from_tuples([("G1Birth",0),("G2Birth",1),("G2Birth",2),("G2Birth",3),
("G1Race",0),("G2Race",1),("G2Race",2),("G2Race",3)])
# Name the columnar index levels
data_df.columns.names = (None, "POS")
# Stack the newly formed lower-level into the rows MultiIndex to complete it in prep for joining
data_df = data_df.stack("POS")
# Join to the id dataframe on the full MultiIndex
final = id_df.join(data_df)
final = final.reset_index()