【问题标题】:Basic Pandas data analysis: connecting data types基本 Pandas 数据分析:连接数据类型
【发布时间】:2016-02-24 23:45:12
【问题描述】:

我加载了一个数据框,其中有一个名为 natvty 的变量,它是 50 到 600 之间数字的频率。每个数字代表一个国家,每个国家出现不止一次。我计算了每个国家出现在列表中的次数。现在我想用国家名称替换国家的数字,例如(57 = 美国)。我尝试了各种 for 循环都无济于事。到目前为止,这是我的代码。在值计数表中,国家编号在左侧,在数据中出现的次数在右侧。我需要用国家名称替换左边的数字。对应于国家名称的数字在外部 Excel 表中的两列中。谢谢。

【问题讨论】:

    标签: python pandas type-conversion


    【解决方案1】:

    我认为一开始可能不需要用国家名称替换国家号码。因为你现在有两张表,一张是列["country_number", "natvty"],另一个(你的excel表,可以导出为.csv文件并由pandas读取)是列["country_number", "country_name"],所以你可以简单地加入它们两者都保留。结果表将有 3 列:分别为 ["country_number", "natvty", "country_name"]

    import pandas as pd
    
    df_nav    = pd.read_csv("my_natvty.csv")
    df_cnames = pd.read_csv("excel_country_names.csv") # or use pd.read_excel("country_names.xlsx") directly on excel files
    
    df_nav_with_cnames = df_nav.join(df_cnames, on='country_number')
    

    确保它们都有一个列 "country_number"。您可以手动修改数据源文件中的表头,或者将它们视为index columns 以同样应用join。这个概念有点像关系数据库中的 SQL 操作。

    文档:http://pandas.pydata.org/pandas-docs/stable/merging.html

    【讨论】:

    • 还有pd.read_excel,所以不用将Excel导出为CSV。
    • @IgorRaush 是的,这当然是一个不错的选择。但我希望数据分析师可以在可访问性不是问题时使用更透明和标准化的格式:)
    【解决方案2】:

    对于这类事情,我总是更喜欢 map 函数,它吃字典,或者是一个函数。

    import pandas as pd
    import numpy.random as np
    In [12]:
    
    print 
    # generate data
    df = pd.DataFrame(data={'natvty':np.randint(low=20,high=500,size=10),
                            'country':pd.Series([1,2,3,3,3,2,1,1,2,3])})
    df
       country  natvty
    0        1      24
    1        2     310
    2        3      88
    3        3     459
    4        3      38
    5        2      63
    6        1     194
    7        1     384
    8        2     281
    9        3     360
    

    然后,dict。在这里我只是输入它,但您可以从 csv 或 excel 文件中加载它。然后,您需要将键设置为索引并将结果系列转换为 dict (to_dict())。

    countrymap = {1:'US',2:'Canada',3:'Mexico'}
    

    然后您可以简单地map 值标签。

    df.country.map(countrymap)
    Out[10]:
    0        US
    1    Canada
    2    Mexico
    3    Mexico
    4    Mexico
    5    Canada
    6        US
    7        US
    8    Canada
    9    Mexico
    Name: country, dtype: objec
    

    【讨论】:

      【解决方案3】:

      注意:这里的基本思想与Shellay's answer相同。我只是想演示如何处理两个数据框中的不同列名,以及如何检索您想要的每个国家/地区的频率。

      您有一个包含国家代码的数据框,以及另一个将国家代码映射到国家名称的数据框。您只需将它们加入国家代码列。您可以阅读有关merging in PandasSQL joins 的更多信息。

      import pandas as pd
      
      # this is your nativity frame
      nt = pd.DataFrame([
          [123],
          [123],
          [456],
          [789],
          [456],
          [456]
      ], columns=('natvty',))
      
      # this is your country code map
      # in reality, use pd.read_excel
      cc = pd.DataFrame([
          [123, 'USA'],
          [456, 'Mexico'],
          [789, 'Canada']
      ], columns=('country_code', 'country_name'))
      
      # perform a join
      # now each row has an associated country_name
      df = nt.merge(cc, left_on='natvty', right_on='country_code')
      
      # now you can get frequencies on country names instead of country codes
      print df.country_name.value_counts(sort=False)
      

      上面的输出是

      Canada    1
      USA       2
      Mexico    3
      Name: country_name, dtype: int64
      

      【讨论】:

      • 谢谢,刚刚意识到我的问题有点模棱两可,因为我没有提供原始数据的格式,但这个答案正是我想要的。
      【解决方案4】:

      我认为字典是你最好的选择。如果您有国家及其代码的字典,例如

      country_dict = {333: 'United States', 123: 'Canada', 456: 'Cuba', ...}
      

      您可能拥有国家及其代码的密钥,因此您可以通过循环非常轻松地制作 dict:

      country_dict = {}
      for i in country_list:
          country = i[0]  # If you had list of countries and their numbers
          number = i[1]
          country_dict[number] = country
      

      一旦有了这个,就可以直接向 DataFrame 添加一列:

      import pandas as pd
      df = pd.read_csv('my_data.csv', header=None)
      df['country'] = [country_dict[x[0][i]] for i in list(df.index)]
      

      如果国家代码列的索引为 0,这应该可以工作

      【讨论】:

      • 这行不通。 df[1] 将返回一个包含所有国家/地区代码的 Series 对象,该对象不能用作普通 Python 字典的键。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      • 2013-10-15
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 1970-01-01
      相关资源
      最近更新 更多