我有以下数据框:
population GDP
country
United Kingdom 4.5m 10m
Spain 3m 8m
France 2m 6m
我在2列数据框中也有以下信息(很高兴将其作为另一个数据结构,如果这将更有益,因为计划是它将在VARS文件中排序。
county code
Spain es
France fr
United Kingdom uk
“映射”数据结构将按随机顺序排序,因为将随机添加/删除国家/地区。
从国家/地区名称将数据框重新索引到其国家/地区代码的最佳方法是什么?
是否有一个智能解决方案也适用于其他列,例如,如果数据框是在日期编制索引但是一列是df['county']
那么您可以将df['country']
更改为其国家/地区代码?最后是否有第三个选项可以添加一个额外的列,该列是国家/代码,它根据另一列中的国家/地区名称选择了正确的代码?
答案 0 :(得分:2)
我认为您可以使用Series.map
,但它仅适用于Series
,因此需要Index.to_series
。上次rename_axis
(pandas
0.18.0
中的新内容):
df1.index = df1.index.to_series().map(df2.set_index('county').code)
df1 = df1.rename_axis('county')
#pandas bellow 0.18.0
#df1.index.name = 'county'
print (df1)
population GDP
county
uk 4.5m 10m
es 3m 8m
fr 2m 6m
与dict
:
d = df2.set_index('county').code.to_dict()
print (d)
{'France': 'fr', 'Spain': 'es', 'United Kingdom': 'uk'}
df1.index = df1.index.to_series().map(d)
df1 = df1.rename_axis('county')
#pandas bellow 0.18.0
#df1.index.name = 'county'
print (df1)
population GDP
county
uk 4.5m 10m
es 3m 8m
fr 2m 6m
编辑:
使用Index.map
的另一个解决方案,因此省略to_series
:
d = df2.set_index('county').code.to_dict()
print (d)
{'France': 'fr', 'Spain': 'es', 'United Kingdom': 'uk'}
df1.index = df1.index.map(d.get)
df1 = df1.rename_axis('county')
#pandas bellow 0.18.0
#df1.index.name = 'county'
print (df1)
population GDP
county
uk 4.5m 10m
es 3m 8m
fr 2m 6m
答案 1 :(得分:0)
以下是一些简短的方法来解决您的3个问题。更多详情如下:
1)如何根据单独的df
中的映射来更改索引使用df_with_mapping.todict("split")
创建字典,然后使用列表推导将其更改为{"old1":"new1",...,"oldn":"newn"}
表单,然后使用df.index = df.base_column.map(dictionary)
获取更改的索引。
2)如果新列在同一个df中,如何更改索引:
df.index = df["column_you_want"]
3)通过映射旧列来创建新列:
df["new_column"] = df["old_column"].map({"old1":"new1",...,"oldn":"newn"})
1)当前索引的映射存在于单独的数据框中,但您还没有数据框中的映射列
这与问题2基本相同,还有为您想要的映射创建字典的附加步骤。
#creating the mapping dictionary in the form of current index : future index
df2 = pd.DataFrame([["es"],["fr"]],index = ["spain","france"])
interm_dict = df2.to_dict("split") #Creates a dictionary split into column labels, data labels and data
mapping_dict = {country:data[0] for country,data in zip(interm_dict["index"],interm_dict['data'])}
#We only want the first column of the data and the index so we need to make a new dict with a list comprehension and zip
df["country"] = df.index #Create a new column if u want to save the index
df.index = pd.Series(df.index).map(mapping_dict) #change the index
df.index.name = "" #Blanks out index name
df = df.drop("county code",1) #Drops the county code column to avoid duplicate columns
在:
county code language
spain es spanish
france fr french
后:
language country
es spanish spain
fr french france
2)将当前索引更改为数据框中已有的列之一
df = pd.DataFrame([["es","spanish"],["fr","french"]], columns = ["county code","language"], index = ["spain", "french"])
df["country"] = df.index #if you want to save the original index
df.index = df["county code"] #The only step you actually need
df.index.name = "" #if you want a blank index name
df = df.drop("county code",1) #if you dont want the duplicate column
在:
county code language
spain es spanish
french fr french
后:
language country
es spanish spain
fr french french
3)根据其他列创建其他列
除了我们创建一个额外的列而不是为创建的系列分配.index
之外,这与第2步基本相同。
df = pd.DataFrame([["es","spanish"],["fr","french"]], columns = ["county code","language"], index = ["spain", "france"])
df["city"] = df["county code"].map({"es":"barcelona","fr":"paris"})
在:
county code language
spain es spanish
france fr french
后:
county code language city
spain es spanish barcelona
france fr french paris