簡體   English   中英

Pandas:append 行到 DataFrame,列中有多個索引

[英]Pandas: append row to DataFrame with multiindex in columns

我有一個 DataFrame,在列中有一個多索引,並且想使用字典來 append 新行。

假設 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:

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

dataframe 的結構看起來不錯。 雖然pandas已經添加了Nans作為默認值?

數據框的布局

現在我想為新城市建立一個字典並添加它:

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

但這失敗了:

ValueError:值的長度與索引的長度不匹配

這是完整的錯誤消息(pastebin)

更新:

謝謝你所有的好答案。 恐怕我在我的例子中把問題簡單化了。 實際上我的索引嵌套了 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

或者,如果您不想首先創建空數據框,則可以使用此方法使用新數據創建數據框。

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執行內部數據對齊,因此將此系列追加到數據幀將自動對齊和添加新的數據幀記錄。

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

多索引是一個tuple list ,我們只需要修改你的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

更多信息

d
Out[995]: 
{('far', 'bike'): 0,
 ('far', 'car'): 1,
 ('near', 'bike'): 1,
 ('near', 'car'): 0}

df.columns.values
Out[996]: array([('near', 'bike'), ('near', 'car'), ('far', 'bike'), ('far', 'car')], dtype=object)

我認為您甚至不需要初始化空數據幀。 使用你的d ,我可以使用unstack和轉置獲得你想要的輸出:

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

   far     near    
  bike car bike car
0    0   1    1   0

使用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堆疊(將生成一個系列),然后通過使用相關城市名稱調用( 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

只是為了添加所有答案,這只是另一個(可能沒有太大不同)簡單示例,以更可重現的方式表示:

import itertools as it
from IPython.display import display # this is just for displaying output purpose
import numpy as np
import pandas as pd

col_1, col_2 = ['A', 'B'], ['C', 'D']
arr_size = len(col_2)
col = pd.MultiIndex.from_product([col_1, col_2])
tmp_df = pd.DataFrame(columns=col)
display(tmp_df)

for s in range(3):# no of rows to add to tmp_df
    tmp_dict = {x : [np.random.random_sample(1)[0] for i in range(arr_size)] for x in range(arr_size)}
    tmp_ser = pd.Series(it.chain.from_iterable([tmp_dict[x] for x in tmp_dict]), index=col)
    #  display(tmp_dict, tmp_ser)
    tmp_df = tmp_df.append(tmp_ser[tmp_df.columns], ignore_index=True)

display(tmp_df)

上面的一些注意事項:

  • 要添加的項目數應始終匹配len(col_1)*len(col_2) ,即構成多索引的元素長度的乘積。
  • list(it.chain.from_iterable([[2, 3], [4, 5]]))只是這樣做 [2,3,4,5]

試試這個解決方法

  • 附加到字典
  • 然后轉換為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')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM