Python数据帧-每N行iloc

Python数据帧-每N行iloc,python,pandas,Python,Pandas,我有一个数据帧“代码”,它是3列36行 我已经成功地使用iloc选择了数据帧中的每N行。我下面的代码每12行正确分配一次,詹姆斯从第0行开始,史蒂夫从第4行开始,加里从第8行开始。每人留三排 James = Codes.iloc[0::12, :] Steve = Codes.iloc[4::12, :] Gary = Codes.iloc[8::12, :] 从这里开始,如何修改代码以分配中间的行?因此,为James分配前4行(0到3),为Steve分配第二4行(4到7),为Gary分配第三

我有一个数据帧“代码”,它是3列36行

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

James = Codes.iloc[0::12, :]
Steve = Codes.iloc[4::12, :]
Gary = Codes.iloc[8::12, :]
从这里开始,如何修改代码以分配中间的行?因此,为James分配前4行(0到3),为Steve分配第二4行(4到7),为Gary分配第三4行(8到11)。 直观地看,它应该是这样的:

James = Codes.iloc[0:3:12, :]
Steve = Codes.iloc[4:7:12, :]
Gary = Codes.iloc[8:11:12, :]
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]
但它只选择了每个名字的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]]

但这是一个冗长的过程,对我处理大型数据集没有帮助,我希望将其应用到一个可行的方法是首先使用
范围
arange
numpy
中获取第n行(在您的例子中是12行),然后进行列表理解,从每行中获取下一个n行(例如3行)。这里我输入了4,因为
范围
arange
函数都忽略了最后一个值

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

仅使用内置的
功能:

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]
其中
i
是您的起始位置(詹姆斯为0,史蒂夫为4,加里为8),
df
是您的数据帧(例如代码)


要使代码具有可伸缩性,可以将其放入函数中,如下所示:

James = Codes.iloc[0:3:12, :]
Steve = Codes.iloc[4:7:12, :]
Gary = Codes.iloc[8:11:12, :]
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]

您可以在数据框中添加一个名为
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"]

我可以让它工作,我理解詹姆斯,但我不确定如何为史蒂夫和加里写它。你能解释一下吗?顺便说一句,非常感谢你的帮助!我已经添加了一些信息,请看看它是否适合你。要使其适用于Steve和Gay,您应该更改
i
值,就像您在示例(0,4,8)中所做的那样。请注意:
.iloc
中的切片表示法不包括在内,这意味着忽略最后一个整数值。因此,如果您想获取四个值(从0到3),则必须指定从0到4(
.iloc[0:4]
)。太棒了!简单得多+1