gpt4 book ai didi

python - 在按 MultiIndex 名称选择时如何分配给 Pandas DataFrame?

转载 作者:行者123 更新时间:2023-11-30 21:51:59 25 4
gpt4 key购买 nike

主要问题:如何使用 MultiIndex 级别的名称来选择/切片多索引 DataFrame,并允许我分配给该切片?

测试数据

data = io.StringIO('''Fruit,Color,Count,Price
Apple,Red,3,$1.29
Apple,Green,9,$0.99
Pear,Red,25,$2.59
Pear,Green,26,$2.79
Lime,Green,9999,$0.39
''')
df_fruit = pd.read_csv(data, index_col=['Fruit', 'Color'])

new_green_data = io.StringIO('''Fruit,Count,Price
Apple,2,$0.96
Lime,9993,$0.40
Pear,12,$2.90
''')
df_new_green = pd.read_csv(new_green_data, index_col='Fruit')

这设置了两个 DataFrame:

df_fruit:

| Fruit   | Color   |   Count | Price   |
|:--------|:--------|--------:|:--------|
| Apple | Red | 3 | $1.29 |
| Apple | Green | 9 | $0.99 |
| Pear | Red | 25 | $2.59 |
| Pear | Green | 26 | $2.79 |
| Lime | Green | 9999 | $0.39 |

df_new_green:

| Fruit   |   Count | Price   |
|:--------|--------:|:--------|
| Apple | 2 | $0.96 |
| Lime | 9993 | $0.40 |
| Pear | 12 | $2.90 |

想要的

我想更新 df_fruit 中的行,其中 ColorGreen,以便它们与传入 中的值匹配>df_new_green 数据。最终输出应该是:

| Fruit   | Color   |   Count | Price   |
|:--------|:--------|--------:|:--------|
| Apple | Red | 3 | $1.29 |
| Apple | Green | 2 | $0.96 |
| Pear | Red | 25 | $2.59 |
| Pear | Green | 12 | $2.90 |
| Lime | Green | 9993 | $0.40 |

请注意,df_new_green 中水果的顺序与 df_fruit 不同。因此,在执行赋值时,我需要保留两侧的索引,以便正确处理。

我所知道的

我知道有几种方法可以选择要在 DataFrame 中更新的内容:

df_fruit.xs(key='Green', level='Color')

这会产生正确的数据 View ,但我无法分配给它。同样关闭:

df_fruit[df_fruit.index.get_level_values('Color') == 'Green']

idx = pd.IndexSlice
df_fruit.loc[idx[:, 'Green'], :]

两者都给我相同的 View ,但它们仍然包含 MultiIndex 的 Color 级别:

| Fruit   | Color   |   Count | Price   |
|:--------|:--------|--------:|:--------|
| Apple | Green | 9 | $0.99 |
| Pear | Green | 26 | $2.79 |
| Lime | Green | 9999 | $0.39 |

我可以使用df_new_green分配给该 View ,但这会产生NaN,因为df_new_green不包含Color 其索引级别。第二种选择(使用 IndexSlice)也不是很好,因为我不是根据其名称来选择级别,而是根据其在 MultiIndex 中的位置来选择级别。如果我在其中任何一个上运行 droplevel('Green'),我会再次获得正确的 View ,但无法分配给它。

我可以删除新值上的索引,但这会导致使用错误的值:

df_fruit.loc[idx[:, 'Green'], :] = df_new_green._values

这会产生:

| Fruit   | Color   |   Count | Price   |
|:--------|:--------|--------:|:--------|
| Apple | Red | 3 | $1.29 |
| Apple | Green | 2 | $0.96 |
| Pear | Red | 25 | $2.59 |
| Pear | Green | 9993 | $0.40 |
| Lime | Green | 12 | $2.90 |

...但这是错误的,因为梨和酸橙的值被交换了。我需要保留更新 DataFrame 上的索引。

丑陋的方式

df_fruit[df_fruit.index.get_level_values('Color') == 'Green'] = df_new_green.assign(Color='Green').set_index('Color', append=True)

...呃。这会产生正确的答案并满足要求,但是天哪,这太丑了。

最佳答案

我会使用assignset_index然后combine_first:

(df_new_green.assign(Color='Green')
.set_index('Color', append=True)
.combine_first(df_fruit))

输出:

|    | Fruit   | Color   |   Count | Price   |
|---:|:--------|:--------|--------:|:--------|
| 0 | Apple | Green | 2 | $0.96 |
| 1 | Apple | Red | 3 | $1.29 |
| 2 | Lime | Green | 9993 | $0.40 |
| 3 | Pear | Green | 12 | $2.90 |
| 4 | Pear | Red | 25 | $2.59 |

关于python - 在按 MultiIndex 名称选择时如何分配给 Pandas DataFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60010682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com