Python 使用for循环分割数据帧的函数

Python 使用for循环分割数据帧的函数,python,pandas,dataframe,for-loop,Python,Pandas,Dataframe,For Loop,我有数据帧(63列x 7446行)。我要做的是对数据帧进行切片,以使用.iloc()生成由其位置指定的特定列组成的新数据帧 我已经编写了以下代码,但它不起作用,我得到了以下错误: TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [12] of <class 'int'> 所需的输出将具有多个变量,如下所示: split

我有数据帧(63列x 7446行)。我要做的是对数据帧进行切片,以使用
.iloc()
生成由其位置指定的特定列组成的新数据帧

我已经编写了以下代码,但它不起作用,我得到了以下错误:

TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [12] of <class 'int'>
所需的输出将具有多个变量,如下所示:
split1
是具有以下列的数据帧:
col0、col1、col2、col3、col4、col5

然后
split2
是包含以下列的数据帧:
col0、col1、col2、col6、col7、col8

等等,一直到
split20

让我知道这是否有意义,并提前感谢您的帮助

注意:因为数据帧太大,所以我没有包括它的一个片段,但是如果有必要,请告诉我,以便您可以有一个工作示例

编辑:在修复了
loc
iloc
的愚蠢错误后,我现在得到以下错误:

IndexError: list index out of range
更新:根据答案和一些进一步的研究,对代码进行了一些更改,现在我有以下内容:

d = {}
#Function to split df into the 20 joints and save them as csv

    def splitAndSave(df):
        for i in names:
            for j in nums:
                #selects columns to be put into a new dataframe, concatenating them if they are not adjacent
                d["split{0}".format(i)] = pd.concat([df.iloc[:,0:3],df.iloc[:,j:j+3]], axis=1)
        return d
现在的问题是,虽然它动态地更新变量名(
split1、2
等),但对
j
却没有这样做。我得到的结果是

{'split1':       col0   col1        col2  col61  col62  col63
'split2':       col0   col1        col2  col61  col62  col63 ... }
为什么它不通过
nums
循环更新
j
,为什么它只选择最后三列

数据:这是数据帧的一个片段,它由63列组成,下面的前三列(帧、时间、SMPTE)和其他60列与
条形图类似,只是名称不同而已。我仅将这六列作为数据框架的一个概念:

  Frame Time    SMPTE       bar_head_x  bar_head_y  bar_head_z
0   1   0.00    02:45:25:03 -203.3502   1554.3486   1102.8210
1   2   0.01    02:45:25:03 -203.4280   1554.3492   1103.0592
2   3   0.02    02:45:25:03 -203.4954   1554.3234   1103.2794
3   4   0.03    02:45:25:04 -203.5022   1554.2974   1103.4522
4   5   0.04    02:45:25:04 -203.5014   1554.2948   1103.6594
目前,每个分割i的输出基本相同(参见上面的更新)。所需输出为:

{'split1':       col0   col1   col2  col3  col4  col5
 'split2':       col0   col1   col2  col6  col7  col8
 'split3':       col0   col1   col2  col9  col10  col11 ... }

显然,每列都包含来自原始数据帧的相应数据。

看起来您使用的是
.loc
属性,但使用的是整数范围切片器:

pd.concat([df.iloc[:,0:3], df.loc[:,nums[j]:nums[j]+3]], axis=1)
#                         HERE ^

您可能也打算在那里使用
.iloc

看起来您使用的是
.loc
属性,但使用的是整数范围切片器:

pd.concat([df.iloc[:,0:3], df.loc[:,nums[j]:nums[j]+3]], axis=1)
#                         HERE ^
您可能也打算在那里使用
.iloc

编辑#2:

下面的代码将数据帧拆分为多个部分。[注意:在下面的示例数据框中,使用了相同的值,但列名不同。]

# Import libraries
import pandas as pd
import numpy as np

# Create DataFrame
df = pd.DataFrame({
    'Frame': [1,2,3,4,5],
    'Time': [0.00, 0.01,0.02,0.03,0.04],
    'SMPTE': ['02:45:25:03','02:45:25:03','02:45:25:03','02:45:25:04','02:45:25:04'],
    'bar_head_x': [-203.3502, -203.4280,-203.4954,-203.5022,-203.5014],
    'bar_head_y': [1554.3486, 1554.3492,1554.3234,1554.2974,1554.2948],
    'bar_head_z': [1102.8210, 1103.0592,1103.2794,1103.4522,1103.6594],
    'bar_head_x1': [-9203.3502, -203.4280,-203.4954,-203.5022,-99203.5014],
    'bar_head_y1': [91554.3486, 1554.3492,1554.3234,1554.2974,991554.2948],
    'bar_head_z1': [91102.8210, 1103.0592,1103.2794,1103.4522,991103.6594],
    'bar_head_x2': [-77203.3502, -203.4280,-203.4954,-203.5022,-77203.5014],
    'bar_head_y2': [771554.3486, 1554.3492,1554.3234,1554.2974,771554.2948],
    'bar_head_z2': [771102.8210, 1103.0592,1103.2794,1103.4522,771103.6594]
})

# Initialize
#nums = [3, 6, 9]
nums = np.linspace(3, df.shape[1]-3,3).astype(int)

# Function to split (copy-pased code from question above)
def splitAndSave(df):
    i=0 # counter
    d = {} # empty
    for j in nums:
        i+=1
        d["split{0}".format(i)] = pd.concat([df.iloc[:,0:3],df.iloc[:,j:j+3]], axis=1)
    return d

# Call to function
d = splitAndSave(df)
输出

d

{'split1':    Frame  Time        SMPTE  bar_head_x  bar_head_y  bar_head_z
 0      1  0.00  02:45:25:03   -203.3502   1554.3486   1102.8210
 1      2  0.01  02:45:25:03   -203.4280   1554.3492   1103.0592
 2      3  0.02  02:45:25:03   -203.4954   1554.3234   1103.2794
 3      4  0.03  02:45:25:04   -203.5022   1554.2974   1103.4522
 4      5  0.04  02:45:25:04   -203.5014   1554.2948   1103.6594,
 'split2':    Frame  Time        SMPTE  bar_head_x1  bar_head_y1  bar_head_z1
 0      1  0.00  02:45:25:03   -9203.3502   91554.3486   91102.8210
 1      2  0.01  02:45:25:03    -203.4280    1554.3492    1103.0592
 2      3  0.02  02:45:25:03    -203.4954    1554.3234    1103.2794
 3      4  0.03  02:45:25:04    -203.5022    1554.2974    1103.4522
 4      5  0.04  02:45:25:04  -99203.5014  991554.2948  991103.6594,
 'split3':    Frame  Time        SMPTE  bar_head_x2  bar_head_y2  bar_head_z2
 0      1  0.00  02:45:25:03  -77203.3502  771554.3486  771102.8210
 1      2  0.01  02:45:25:03    -203.4280    1554.3492    1103.0592
 2      3  0.02  02:45:25:03    -203.4954    1554.3234    1103.2794
 3      4  0.03  02:45:25:04    -203.5022    1554.2974    1103.4522
 4      5  0.04  02:45:25:04  -77203.5014  771554.2948  771103.6594}
编辑#1:

问题似乎是使用
.loc
而不是
.iloc

尝试替换:

locals()["split"+str(i)] = pd.concat([df.iloc[:,0:3],df.loc[:,nums[j]:nums[j]+3]], axis=1)
为此:

locals()["split"+str(i)] = pd.concat([df.iloc[:,0:3],df.iloc[:,j:j+3]], axis=1)
编辑#2:

下面的代码将数据帧拆分为多个部分。[注意:在下面的示例数据框中,使用了相同的值,但列名不同。]

# Import libraries
import pandas as pd
import numpy as np

# Create DataFrame
df = pd.DataFrame({
    'Frame': [1,2,3,4,5],
    'Time': [0.00, 0.01,0.02,0.03,0.04],
    'SMPTE': ['02:45:25:03','02:45:25:03','02:45:25:03','02:45:25:04','02:45:25:04'],
    'bar_head_x': [-203.3502, -203.4280,-203.4954,-203.5022,-203.5014],
    'bar_head_y': [1554.3486, 1554.3492,1554.3234,1554.2974,1554.2948],
    'bar_head_z': [1102.8210, 1103.0592,1103.2794,1103.4522,1103.6594],
    'bar_head_x1': [-9203.3502, -203.4280,-203.4954,-203.5022,-99203.5014],
    'bar_head_y1': [91554.3486, 1554.3492,1554.3234,1554.2974,991554.2948],
    'bar_head_z1': [91102.8210, 1103.0592,1103.2794,1103.4522,991103.6594],
    'bar_head_x2': [-77203.3502, -203.4280,-203.4954,-203.5022,-77203.5014],
    'bar_head_y2': [771554.3486, 1554.3492,1554.3234,1554.2974,771554.2948],
    'bar_head_z2': [771102.8210, 1103.0592,1103.2794,1103.4522,771103.6594]
})

# Initialize
#nums = [3, 6, 9]
nums = np.linspace(3, df.shape[1]-3,3).astype(int)

# Function to split (copy-pased code from question above)
def splitAndSave(df):
    i=0 # counter
    d = {} # empty
    for j in nums:
        i+=1
        d["split{0}".format(i)] = pd.concat([df.iloc[:,0:3],df.iloc[:,j:j+3]], axis=1)
    return d

# Call to function
d = splitAndSave(df)
输出

d

{'split1':    Frame  Time        SMPTE  bar_head_x  bar_head_y  bar_head_z
 0      1  0.00  02:45:25:03   -203.3502   1554.3486   1102.8210
 1      2  0.01  02:45:25:03   -203.4280   1554.3492   1103.0592
 2      3  0.02  02:45:25:03   -203.4954   1554.3234   1103.2794
 3      4  0.03  02:45:25:04   -203.5022   1554.2974   1103.4522
 4      5  0.04  02:45:25:04   -203.5014   1554.2948   1103.6594,
 'split2':    Frame  Time        SMPTE  bar_head_x1  bar_head_y1  bar_head_z1
 0      1  0.00  02:45:25:03   -9203.3502   91554.3486   91102.8210
 1      2  0.01  02:45:25:03    -203.4280    1554.3492    1103.0592
 2      3  0.02  02:45:25:03    -203.4954    1554.3234    1103.2794
 3      4  0.03  02:45:25:04    -203.5022    1554.2974    1103.4522
 4      5  0.04  02:45:25:04  -99203.5014  991554.2948  991103.6594,
 'split3':    Frame  Time        SMPTE  bar_head_x2  bar_head_y2  bar_head_z2
 0      1  0.00  02:45:25:03  -77203.3502  771554.3486  771102.8210
 1      2  0.01  02:45:25:03    -203.4280    1554.3492    1103.0592
 2      3  0.02  02:45:25:03    -203.4954    1554.3234    1103.2794
 3      4  0.03  02:45:25:04    -203.5022    1554.2974    1103.4522
 4      5  0.04  02:45:25:04  -77203.5014  771554.2948  771103.6594}
编辑#1:

问题似乎是使用
.loc
而不是
.iloc

尝试替换:

locals()["split"+str(i)] = pd.concat([df.iloc[:,0:3],df.loc[:,nums[j]:nums[j]+3]], axis=1)
为此:

locals()["split"+str(i)] = pd.concat([df.iloc[:,0:3],df.iloc[:,j:j+3]], axis=1)

如果列是按顺序排列的,则可以使用以下方法

split1 = df.iloc[:, 0:6]

split2 = df.iloc[:, 0:18]
如果列不按顺序排列,则可以使用这种方式

split1 = df[['col1', 'col2']]
split2 = df[['col0', 'col4']]

如果列是按顺序排列的,则可以使用以下方法

split1 = df.iloc[:, 0:6]

split2 = df.iloc[:, 0:18]
如果列不按顺序排列,则可以使用这种方式

split1 = df[['col1', 'col2']]
split2 = df[['col0', 'col4']]

是的,那是一个愚蠢的错误,我没有注意到,谢谢!!然而,我仍然得到了一个错误,请参阅帖子中的编辑是的,这是一个愚蠢的错误,我没有注意到,谢谢!!然而,我仍然得到了一个错误,请参阅帖子中的编辑,我必须在任何时候都这样做,所以我试图避免手动操作。这就是为什么我尝试使用函数和for循环:)我必须在任何时候都这样做,所以我尽量避免手动操作。这就是为什么我尝试使用函数和for循环:)我已经编辑了答案。循环的
for
使用的是
in
,因此直接使用
j
而不是
nums[j]
,这样就不会给我带来错误了。但是for循环的输出不是我所需要的,它不断输出相同的列,而不是遍历它们,所以所有的split_I都是相同的…你能看到它为什么会这样做吗?根据问题中的可用信息,很难理解传递给函数的数据是什么。查看示例数据帧和所需输出会有所帮助。是的,当然,我在问题中添加了信息,如果这对您现在有帮助的话。谢谢。现在调查一下。如果我能找到任何东西,我会更新这个评论。我已经编辑了答案。循环的
for
使用的是
in
,因此直接使用
j
而不是
nums[j]
,这样就不会给我带来错误了。但是for循环的输出不是我所需要的,它不断输出相同的列,而不是遍历它们,所以所有的split_I都是相同的…你能看到它为什么会这样做吗?根据问题中的可用信息,很难理解传递给函数的数据是什么。查看示例数据帧和所需输出会有所帮助。是的,当然,我在问题中添加了信息,如果这对您现在有帮助的话。谢谢。现在调查一下。如果我能找到任何东西,我会更新这个评论。