【问题标题】:Defining lists based on indices of pandas dataframe根据 pandas 数据框的索引定义列表
【发布时间】:2014-07-17 08:45:04
【问题描述】:

我有一个 pandas 数据框,其中一列将日期值作为字符串(如“2014-01-01”)。我想为列中存在的每一年定义一个不同的列表,其中列表的元素是在数据框中找到年份的行的索引。

这是我尝试过的:

import pandas as pd    

df = pd.DataFrame(["2014-01-01","2013-01-01","2014-02-02", "2012-08-09"])
df = df.values.flatten().tolist()

for i in range(len(df)):
    df[i] = df[i][0:4]

y2012 = []; y2013 = []; y2014 = []

for i in range(len(df)):
    if df[i] == "2012":
        y2012.append(i)
    elif df[i] == "2013":
        y2013.append(i)
    else:
        y2014.append(i)

print y2014 # [0, 2]
print y2013 # [1]
print y2012 # [3]

有人知道更好的方法吗?这种方式很好用,但是我有很多年,所以我必须手动定义每个变量,然后通过 for 循环运行它,所以代码变得很长。我试图在熊猫中使用groupby,但我似乎无法让它工作。

非常感谢您的帮助!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    扫描原始的DataFrame 值并解析出年份。鉴于,将索引添加到默认字典中。也就是说,下面的代码创建了一个dict,每年一个项目。特定年份的值是在数据框中找到该年份的行的列表。

    defaultdict 听起来很吓人,但它只是一本字典。在这种情况下,每个值都是一个列表。如果我们将append 设置为不存在的值,那么它会自发地创建。方便!

    来源

    from collections import defaultdict
    import pandas as pd    
    
    df = pd.DataFrame(["2014-01-01","2013-01-01","2014-02-02", "2012-08-09"])
    # df = df.values.flatten().tolist()
    
    dindex = defaultdict(list)
    for index,dateval in enumerate(df.values):
        year = dateval[0].split('-')[0]
        dindex[year].append(index)
    
    assert dindex == {'2014': [0, 2], '2013': [1], '2012': [3]}
    print dindex
    

    输出

    defaultdict(<type 'list'>, {'2014': [0, 2], '2013': [1], '2012': [3]})
    

    【讨论】:

      【解决方案2】:

      Pandas 对于这种事情来说很棒,所以不要急于马上将你的数据框转回列表。

      这里的诀窍在于.apply() 方法和.groupby() 方法。

      1. 获取一个数据框,其中包含带有 ISO 格式日期的字符串
      2. 将包含日期字符串的列解析为日期时间对象
      3. 使用 datetime.year 创建另一列年份 日期时间列中项目的属性
      4. 按新年列对数据框进行分组
      5. 遍历 groupby 对象并提取列

      这里有一些代码供你玩和摸索:

      import pandas
      import dateutil
      
      df = pd.DataFrame({'strings': ["2014-01-01","2013-01-01","2014-02-02", "2012-08-09"]})
      df['datetimes'] = df['strings'].apply(dateutil.parser.parse)
      df['year'] = df['datetimes'].apply(lambda x: x.year)
      grouped_data= df.groupby('year')
      
      lists_by_year = {}
      for year, data in grouped_data
          lists_by_year [year] = list(data['strings'])
      

      这为我们提供了一个列表字典,其中键是年份,内容是具有该年份的字符串列表。

      print lists_by_year 
      
      {2012: ['2012-08-09'],
       2013: ['2013-01-01'],
       2014: ['2014-01-01', '2014-02-02']}
      

      【讨论】:

        【解决方案3】:

        事实证明

        df.groupby('A') #is just syntactical sugar for df.groupby(df['A'])
        

        这意味着按年份分组所需要做的就是利用 apply 函数并重新编写语法

        解决方案

        getYear = lambda x:x.split("-")[0]
        yearGroups = df.groupby(df["dates"].apply(getYear))
        

        输出

        for key,group in yearGroups: 
            print key
        
        2012
        2013
        2014
        

        【讨论】:

        • 我只打印了 for 循环中的键,该组包含一个包含所有列的数据框对象,您可以根据需要提取数据框、系列或列表
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-01
        • 1970-01-01
        • 2022-06-29
        • 2016-11-14
        • 2015-07-12
        • 2021-10-03
        • 2013-10-09
        相关资源
        最近更新 更多