给定一个具有多重索引列的 pandas DataFrame,如何为每个城市添加一列,该列的值取自与 Code2 字符串映射的 Code 对应的 H 值?
例如,对于以下 DataFrame:
+---+----+------+-----+------+
| H | Nu | City | Code | Code2 |
+---+----+------+-----+------+
| 0.965392 | 15 | Madrid | es | es |
| 0.920614 | 15 | Madrid | it | es |
| 0.726219 | 16 | Madrid | tn | es |
| 0.739119 | 17 | Madrid | fr | es |
| 0.789923 | 55 | Dublin | mt | en |
| 0.699239 | 57 | Dublin | en | en |
| 0.890462 | 68 | Dublin | ar | en |
| 0.746863 | 68 | Dublin | pt | en |
| 0.789923 | 55 | Milano | it | it |
| 0.699239 | 57 | Milano | es | it |
| 0.890462 | 68 | Milano | ar | it |
| 0.746863 | 68 | Milano | pt | it |
+---+----+------+-----+------+
期望的输出是:
+---+----+------+-----+------+-------+
| H | Nu | City | Code | Code2 | HCode |
+---+----+------+-----+------+-------+
| 0.965392 | 15 | Madrid | es | es | 0.965392 |
| 0.920614 | 15 | Madrid | it | es | 0.965392 |
| 0.726219 | 16 | Madrid | tn | es | 0.965392 |
| 0.739119 | 17 | Madrid | fr | es | 0.965392 |
| 0.789923 | 55 | Dublin | mt | en | 0.699239 |
| 0.699239 | 57 | Dublin | en | en | 0.699239 |
| 0.890462 | 68 | Dublin | ar | en | 0.699239 |
| 0.746863 | 68 | Dublin | pt | en | 0.699239 |
| 0.789923 | 55 | Milano | it | it | 0.789923 |
| 0.699239 | 57 | Milano | es | it | 0.789923 |
| 0.890462 | 68 | Milano | ar | it | 0.789923 |
| 0.746863 | 68 | Milano | pt | it | 0.789923 |
+---+----+------+-----+------+-------+
解决方案
方法一:
- 使用
groupby()
和first()
方法对 DataFrame 按City
和Code2
列分组,并获取H
列的第一个值。 - 将分组后的结果与原始 DataFrame 合并,使用
left_on
和right_on
参数指定连接键。 - 使用
ffill()
方法填充合并后的 DataFrame 中的缺失值。
import pandas as pd
# 初始DataFrame
df = pd.DataFrame({
'H': [0.965392, 0.920614, 0.726219, 0.739119, 0.789923, 0.699239, 0.890462, 0.746863, 0.789923, 0.699239, 0.890462, 0.746863],
'Nu': [15, 15, 16, 17, 55, 57, 68, 68, 55, 57, 68, 68],
'City': ['Madrid', 'Madrid', 'Madrid', 'Madrid', 'Dublin', 'Dublin', 'Dublin', 'Dublin', 'Milano', 'Milano', 'Milano', 'Milano'],
'Code': ['es', 'it', 'tn', 'fr', 'mt', 'en', 'ar', 'pt', 'it', 'es', 'ar', 'pt'],
'Code2': ['es', 'es', 'es', 'es', 'en', 'en', 'en', 'en', 'it', 'it', 'it', 'it']
})
# 分组并获取H列的第一个值
gp = df.groupby(['City', 'Code2'])['H'].first().reset_index()
# 合并数据
df = df.merge(gp, left_on=['City', 'Code'], right_on=['City', 'Code2'], how='left')
# 填充缺失值
df['HCode'] = df['H_y'].ffill()
# 删除多余列
df = df.drop('H_y', axis=1)
# 打印结果
print(df)
方法二:
- 使用
groupby()
和apply()
方法对 DataFrame 按City
列分组,并获取每个组中满足Code2
等于Code
条件的行的H
值。 - 将分组后的结果与原始 DataFrame 合并,使用
left_on
和right_on
参数指定连接键。 - 使用
ffill()
方法填充合并后的 DataFrame 中的缺失值。
# 初始DataFrame
df = pd.DataFrame({
'H': [0.965392, 0.920614, 0.726219, 0.739119, 0.789923, 0.699239, 0.890462, 0.746863, 0.789923, 0.699239, 0.890462, 0.746863],
'Nu': [15, 15, 16, 17, 55, 57, 68, 68, 55, 57, 68, 68],
'City': ['Madrid', 'Madrid', 'Madrid', 'Madrid', 'Dublin', 'Dublin', 'Dublin', 'Dublin', 'Milano', 'Milano', 'Milano', 'Milano'],
'Code': ['es', 'it', 'tn', 'fr', 'mt', 'en', 'ar', 'pt', 'it', 'es', 'ar', 'pt'],
'Code2': ['es', 'es', 'es', 'es', 'en', 'en', 'en', 'en', 'it', 'it', 'it', 'it']
})
# 分组并获取满足条件的H值
gp = df.groupby('City').apply(lambda x: x[x['Code2'] == x['Code']]['H'].values[0])
# 合并数据
df['HCode'] = df['City'].map(gp)
# 填充缺失值
df['HCode'] = df['HCode'].ffill()
# 打印结果
print(df)