Python Dataframe - iloc every nth rows



我有一个数据帧"Codes",它是3列36行。

我已经成功地使用iloc来选择数据帧中的每n行。我下面的代码正确地分配了每12行,从第0行开始为詹姆斯,第4行为史蒂夫,第8行为加里。每人3排。

James = Codes.iloc[0::12, :]
Steve = Codes.iloc[4::12, :]
Gary = Codes.iloc[8::12, :]

接下来,我如何修改代码以分配中间的行?因此,将前4行(0到3(分配给詹姆斯,将第二行(4到7(分配给史蒂夫,将第三行(8到11(分配给加里。直观地看应该是这样的:

James = Codes.iloc[0:3:12, :]
Steve = Codes.iloc[4:7:12, :]
Gary = Codes.iloc[8:11:12, :]

但每个名字只选择1行,因为代码在詹姆斯的3行、史蒂夫的7行和加里的11行之后结束。如果我让它正常工作,它会在3个人之间分割我的36行数据帧,给他们每个4块12行。

这个脚本完成了以下工作:

James = Codes.iloc [[0,1,2,3, 12,13,14,15, 24,25,26,27]]
Steve = Codes.iloc [[4,5,6,7, 16,17,18,19, 28,29,30,31]]
Gary = Codes.iloc [[8,9,10,11, 20,21,22,23, 32,33,34,35]]

但它很冗长,对我处理大型数据集没有帮助,我希望将其应用于

您可以在数据帧中添加一个名为name的列,并在该列中填充要分配该行的名称。

from itertools import cycle, islice
name_pattern = ["James"]*4 + ["Steve"]*4 + ["Gary"]*4
Code["name"] = list(islice(cycle(name_pattern), Code.shape[0]))

最后一行只是重复数据帧中的行数模式。然后,如果你仍然想把这些行保存到单独的数据帧中,你可以去

James = Code[Code["name"]=="James"]
Steve = Code[Code["name"]=="Steve"]
Gary = Code[Code["name"]=="Gary"]

一种可能的方法是首先使用rangenumpy中的arange获得第n行(在本例中为12行(,然后进行列表理解,从每行中获得下一个n行(例如3行(。这里我键入了4,因为rangearange函数都忽略了最后一个值。

可能会在数据帧的行范围之外获取索引,因此从索引列表中筛选出索引非常重要。

仅使用built-in函数:

i = 0 # starting position
arange = range(i, df.shape[0]+1, 12) # get the indexes each 12th position starting from `i`
idx = sum([list(range(i,i+4)) for i in arange], []) # for each index, get the next 3
idx = list(filter(lambda x: x < df.shape[0], idx)) # remove possible outlier indexes
df.iloc[idx]

使用numpy:

import numpy as np
i = 0 # starting position
arange = np.arange(i, df.shape[0]+1, 12) # get the indexes each 12th position starting from `i`
idx = np.array([list(range(i,i+4)) for i in arange]).flatten() # for each index, get the next 3
idx = idx[idx <= df.shape[0]] # remove possible outlier indexes
df.iloc[idx]

其中i是您的起始位置(James为0,Steve为4,Gary为8(,
df是您的数据帧(例如代码(


要使代码可伸缩,您可以将其放入一个函数中,如下所示:

def slice_df(df, startpos, gsize, nth):
"""
Slice the data based on start position, group size and nth row
df : pandas DataFrame
startpos : int
start position for the target-value (e.g. person)
gsize : int
group size (plus 1)
nth : int
slice dataframe every nth rows
"""
i = startpos
arange = range(i, df.shape[0]+1, nth) 
idx = sum([list(range(i,i+gsize)) for i in arange], [])
idx = list(filter(lambda x: x < df.shape[0], idx))
return df.iloc[idx]

然后呼叫:

James = slice_df(df, 0, 4, 12)
Steve = slice_df(df, 4, 4, 12)
Gary = slice_df(df, 8, 4, 12)

最新更新