Pandas:使用列中的multiindex将行附加到DataFrame

时间:2017-11-16 20:05:23

标签: python pandas dataframe data-structures

我在列中有一个带有多索引的DataFrame,并希望使用词典附加新行。

假设DataFrame中的每一行都是一个城市。列包含“距离”和“车辆”。并且每个单元格将是在此距离内选择此车辆的人口的百分比。

我正在构建一个这样的索引:

index_tuples=[]

for distance in ["near", "far"]:
    for vehicle in ["bike", "car"]:
        index_tuples.append([distance, vehicle])

index = pd.MultiIndex.from_tuples(index_tuples, names=["distance", "vehicle"])

然后我正在创建一个数据帧:

dataframe = pd.DataFrame(index=["city"], columns = index)

数据框的结构看起来不错。虽然pandas已将Nans添加为默认值?

layout of the dataframe

现在我想为新城市设置字典并添加它:

my_home_city = {"near":{"bike":1, "car":0},"far":{"bike":0, "car":1}}
dataframe["my_home_city"] = my_home_city

但这失败了:

  

ValueError:值的长度与索引的长度

不匹配

这是完整的error message(pastebin)

更新

谢谢你们所有的好答案。我担心我的例子中的问题过于简单了。实际上我的索引嵌套了3个级别(它可能会变得更多)。

所以我接受了将字典转换为元组列表的通用答案。这可能不像其他方法那样干净,但适用于任何多索引设置。

5 个答案:

答案 0 :(得分:3)

您可以像这样附加到数据框:

my_home_city = {"near":{"bike":1, "car":0},"far":{"bike":0, "car":1}}
dataframe.append(pd.DataFrame.from_dict(my_home_city).unstack().rename('my_home_city'))

输出:

distance     near       far     
vehicle      bike  car bike  car
city          NaN  NaN  NaN  NaN
my_home_city    1    0    0    1

诀窍是使用from_dict然后unstack创建数据框行,以使用多索引列获取原始数据框的结构,然后rename获取索引和append。< / p>

或者,如果您不想先创建空数据框,可以使用此方法创建包含新数据的数据框。

pd.DataFrame.from_dict(my_home_city).unstack().rename('my_home_city').to_frame().T

输出:

              far     near    
             bike car bike car
my_home_city    0   1    1   0

<强>解释

pd.DataFrame.from_dict(my_home_city)

      far  near
bike    0     1
car     1     0

现在,让我们卸载创建多索引并将新数据帧转换为原始数据帧的结构。

pd.DataFrame.from_dict(my_home_city).unstack()

far   bike    0
      car     1
near  bike    1
      car     0
dtype: int64

我们使用重命名为该系列赋予一个名称,该名称在附加到原始数据帧时成为该数据帧行的索引标签。

far   bike    0
      car     1
near  bike    1
      car     0
Name: my_home_city, dtype: int64

现在,如果您将该系列转换为一个帧并进行转置,它看起来非常像一个新行,但是,没有必要这样做,因为Pandas执行内部数据对齐,因此将此系列追加到数据帧将自动-align并添加新的数据帧记录。

dataframe.append(pd.DataFrame.from_dict(my_home_city).unstack().rename('my_home_city'))
distance     near       far     
vehicle      bike  car bike  car
city          NaN  NaN  NaN  NaN
my_home_city    1    0    0    1

答案 1 :(得分:3)

多索引是list的{​​{1}},我们只需修改您的tuple,然后我们就可以直接指定值

dict

更多信息

d = {(x,y):my_home_city[x][y] for x in my_home_city for y in my_home_city[x]}
df.loc['my_home_city',:]=d
df
Out[994]: 
distance     near       far     
vehicle      bike  car bike  car
city          NaN  NaN  NaN  NaN
my_home_city    1    0    0    1

答案 2 :(得分:2)

我认为你甚至不需要初始化一个空的数据帧。使用d,我可以使用unstack和转置获得所需的输出:

pd.DataFrame(d).unstack().to_frame().T

   far     near    
  bike car bike car
0    0   1    1   0

答案 3 :(得分:1)

使用MultiIndex.from_product初始化空数据框。

distances = ['near', 'far']
vehicles = ['bike', 'car']
df = pd.DataFrame([], columns=pd.MultiIndex.from_product([distances, vehicles]), 
                  index=pd.Index([], name='city'))

你的字典会产生一个方形矩阵(车辆距离),所以将它取消堆叠(这将产生一个系列),然后通过使用相关的城市名称调用(to_frame)将其转换为数据帧行。将列转换成一行。

>>> df.append(pd.DataFrame(my_home_city).unstack().to_frame('my_home_city').T)
              far     near    
             bike car bike car
city                          
my_home_city    0   1    1   0

答案 4 :(得分:0)

尝试此解决方法

  • 追加到dict
  • 然后转换为pandas数据框
  • 在最后一步选择所需的列以使用set_index()
  • 创建多索引
d = dict()
for g in predictor_types:
    for col in predictor_types[g]:
        tot = len(ames) - ames[col].count()
        if tot:
            d.setdefault('type',[]).append(g)
            d.setdefault('predictor',[]).append(col)
            d.setdefault('missing',[]).append(tot)
pd.DataFrame(d).set_index(['type','predictor']).style.bar(color='DodgerBlue')