【问题标题】:Pandas every nth row熊猫每 n 行
【发布时间】:2014-09-23 05:02:19
【问题描述】:

Dataframe.resample() 仅适用于时间序列数据。我找不到从非时间序列数据中获取每 n 行的方法。最好的方法是什么?

【问题讨论】:

    标签: python pandas resampling


    【解决方案1】:

    我会使用iloc,它采用行/列切片,既基于整数位置,又遵循正常的python语法。如果你想要每 5 行:

    df.iloc[::5, :]
    

    【讨论】:

    • 对于那些可能想要的人,例如,每五行,但从第二行开始,它将是df.iloc[1::5, :]
    • 可以省略列部分:df.iloc[::5]
    • @chrisb 如何指定起始行?像每 5 行一样,从第二行开始?
    • 你如何从后面包含它?
    • @banderlog013 不,这很直观 - 只需 df.iloc[::3] 就足够了。您想要(“直观地”)是选择的第一行不是数据框中的第一行。不难看出,对于任何给定的 N(“给我 N 行,从自然计数的第 N 行开始”),索引是 df.iloc[(N-1)::N]。这种行为很少需要,但是...
    【解决方案2】:

    虽然@chrisb 接受的答案确实回答了这个问题,但我想补充以下内容。

    我用来获取nth 数据或删除nth 行的简单方法如下:

    df1 = df[df.index % 3 != 0]  # Excludes every 3rd row starting from 0
    df2 = df[df.index % 3 == 0]  # Selects every 3rd raw starting from 0
    

    这种基于算术的采样能够实现更复杂的行选择。

    假设,当然,您有一个从 0 开始的 有序、连续、整数index 列。

    【讨论】:

    • 这不是一个好的答案,因为做了三个假设,这些假设经常不满足:(1)索引是数字的(2)它从零开始的索引(3)索引值是连续的。 .. 最后一个特别重要,因为您不能在不重置索引的情况下多次使用建议的方法
    • 我同意你的观点。将编辑答案以使假设更明确
    • @Constantine 仍然会比其他解决方案更快,因为您可以简单地添加索引?
    【解决方案3】:

    我有类似的要求,但我想要特定组中的第 n 个项目。我就是这样解决的。

    groups = data.groupby(['group_key'])
    selection = groups['index_col'].apply(lambda x: x % 3 == 0)
    subset = data[selection]
    

    【讨论】:

      【解决方案4】:

      对于已接受的答案,还有一个更简单的解决方案,即直接调用df.__getitem__

      df = pd.DataFrame('x', index=range(5), columns=list('abc'))
      df
      
         a  b  c
      0  x  x  x
      1  x  x  x
      2  x  x  x
      3  x  x  x
      4  x  x  x
      

      例如,要获取每 2 行,您可以这样做

      df[::2]
      
         a  b  c
      0  x  x  x
      2  x  x  x
      4  x  x  x
      

      还有GroupBy.first/GroupBy.head,你在索引上分组:

      df.index // 2
      # Int64Index([0, 0, 1, 1, 2], dtype='int64')
      
      df.groupby(df.index // 2).first()
      # Alternatively,
      # df.groupby(df.index // 2).head(1)
      
         a  b  c
      0  x  x  x
      1  x  x  x
      2  x  x  x
      

      索引按步幅(在本例中为 2)进行地板分割。如果索引是非数字的,则改为这样做

      # df.groupby(np.arange(len(df)) // 2).first()
      df.groupby(pd.RangeIndex(len(df)) // 2).first()
      
         a  b  c
      0  x  x  x
      1  x  x  x
      2  x  x  x
      

      【讨论】:

        【解决方案5】:

        我在使用索引时提出的解决方案不可行(可能是多 Gig .csv 太大,或者我错过了一些可以让我重新索引而不会崩溃的技术)。
        一次遍历一行并将第 n 行添加到新数据帧。

        import pandas as pd
        from csv import DictReader
        
        def make_downsampled_df(filename, interval):    
            with open(filename, 'r') as read_obj:
                csv_dict_reader = DictReader(read_obj)
                column_names = csv_dict_reader.fieldnames
                df = pd.DataFrame(columns=column_names)
            
                for index, row in enumerate(csv_dict_reader):
                    if index % interval == 0:
                       print(str(row))
                       df = df.append(row, ignore_index=True)
        
            return df
        

        【讨论】:

          【解决方案6】:
          df.drop(labels=df[df.index % 3 != 0].index, axis=0) #  every 3rd row (mod 3)
          

          【讨论】:

          • 虽然这段代码可能会回答这个问题,including an explanation 关于如何或为什么解决问题将真正有助于提高您的帖子质量。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
          【解决方案7】:

          reset_index() 添加到metastableB's answer 允许您只需要假设行是有序且连续的

          df1 = df[df.reset_index().index % 3 != 0]  # Excludes every 3rd row starting from 0
          df2 = df[df.reset_index().index % 3 == 0]  # Selects every 3rd row starting from 0
          

          df.reset_index().index 将创建一个从 0 开始并以 1 递增的索引,让您可以轻松地使用模数。

          【讨论】:

            猜你喜欢
            • 2021-07-07
            • 2019-01-24
            • 1970-01-01
            • 2018-04-24
            • 2018-07-27
            • 1970-01-01
            • 2017-07-09
            • 1970-01-01
            • 2018-12-12
            相关资源
            最近更新 更多