Pandas:按行数将数据帧拆分为多个数据帧

时间:2014-08-13 15:53:35

标签: python pandas split dataframe

对熊猫来说相当新,所以忍受我...

我有一个巨大的csv,包含很多行的许多表。我想简单地将每个数据帧拆分为2,如果它包含超过10行。

如果为true,我希望第一个数据帧包含前10个数据帧,其余数据帧包含第二个数据帧。

这是否有方便的功能?我环顾四周但没有发现任何有用的东西......

即。 split_dataframe(df,2(if> 10))?

9 个答案:

答案 0 :(得分:18)

如果满足条件,这将返回拆分的DataFrame,否则返回原始文件和None(然后您需要单独处理)。请注意,这假设分割只需要每df发生一次,并且拆分的第二部分(如果长度超过10行(意味着原始长度超过20行))就可以了。< / p>

df_new1, df_new2 = df[:10, :], df[10:, :] if len(df) > 10 else df, None

请注意,您也可以根据需要使用df.head(10)df.tail(len(df) - 10)来获取正面和背面。您还可以使用各种索引方法:您可以根据需要提供第一个维度索引,例如df[:10]而不是df[:10, :](尽管我喜欢明确地编写您正在考虑的维度)。您也可以使用df.ilocdf.ix以类似方式进行索引。

谨慎使用df.loc,因为it is label-based and the input will never be interpreted as an integer position.loc只会在您碰巧拥有从0开始且没有间隙的整数的索引标签时“意外”工作。

但是您还应该考虑pandas提供的各种选项,用于将DataFrame的内容转储为HTML,还可能考虑LaTeX,以便为演示文稿制作更好的表格(而不仅仅是复制和粘贴)。只需谷歌搜索如何将DataFrame转换为这些格式,就可以为这个应用程序提供大量的教程和建议。

答案 1 :(得分:13)

没有特定的便利功能。

你必须做类似的事情:

first_ten = pd.DataFrame()
rest = pd.DataFrame()

if df.shape[0] > 10: # len(df) > 10 would also work
    first_ten = df[:10]
    rest = df[10:]

答案 2 :(得分:5)

我用这个List Comprehensions将一个巨大的df切成100'000的块:

size = 100000
list_of_dfs = [df.loc[i:i+size-1,:] for i in range(0, len(df),size)]

或作为生成器:

list_of_dfs = (df.loc[i:i+size-1,:] for i in range(0, len(df),size))

答案 3 :(得分:2)

基于np.split的方法:

df = pd.DataFrame({    'A':[2,4,6,8,10,2,4,6,8,10],
                       'B':[10,-10,0,20,-10,10,-10,0,20,-10],
                       'C':[4,12,8,0,0,4,12,8,0,0],
                      'D':[9,10,0,1,3,np.nan,np.nan,np.nan,np.nan,np.nan]})

listOfDfs = [df.loc[idx] for idx in np.split(df.index,5)]

使用模数的小函数可以处理拆分不均匀的情况(例如np.split(df.index,4)会抛出错误)。

是的,我知道原来的问题比这更具体。但是,这应该回答标题中的问题。

答案 4 :(得分:1)

您可以使用DataFrame head和tail方法作为语法糖而不是切片/ loc。我使用3的分割大小;对于您的示例,请使用headSize = 10

def split(df, headSize) :
    hd = df.head(headSize)
    tl = df.tail(len(df)-headSize)
    return hd, tl

df = pd.DataFrame({    'A':[2,4,6,8,10,2,4,6,8,10],
                       'B':[10,-10,0,20,-10,10,-10,0,20,-10],
                       'C':[4,12,8,0,0,4,12,8,0,0],
                      'D':[9,10,0,1,3,np.nan,np.nan,np.nan,np.nan,np.nan]})

# Split dataframe into top 3 rows (first) and the rest (second)
first, second = split(df, 3)

答案 5 :(得分:1)

下面是一个简单的函数实现,它将DataFrame分为多个块和一些代码示例:

import pandas as pd

def split_dataframe_to_chunks(df, n):
    df_len = len(df)
    count = 0
    dfs = []

    while True:
        if count > df_len-1:
            break

        start = count
        count += n
        #print("%s : %s" % (start, count))
        dfs.append(df.iloc[start : count])
    return dfs


# Create a DataFrame with 10 rows
df = pd.DataFrame([i for i in range(10)])

# Split the DataFrame to chunks of maximum size 2
split_df_to_chunks_of_2 = split_dataframe_to_chunks(df, 2)
print([len(i) for i in split_df_to_chunks_of_2])
# prints: [2, 2, 2, 2, 2]

# Split the DataFrame to chunks of maximum size 3
split_df_to_chunks_of_3 = split_dataframe_to_chunks(df, 3)
print([len(i) for i in split_df_to_chunks_of_3])
# prints [3, 3, 3, 1]

答案 6 :(得分:0)

如果您有一个大型数据框并且需要划分为可变数量的子数据帧行,例如每个子数据帧最多有4500行,则此脚本可以提供帮助:

max_rows = 4500
dataframes = []
while len(df) > max_rows:
    top = df[:max_rows]
    dataframes.append(top)
    df = df[max_rows:]
else:
    dataframes.append(df)

然后您可以保存这些数据框:

for _, frame in enumerate(dataframes):
    frame.to_csv(str(_)+'.csv', index=False)

希望这有助于某人!

答案 7 :(得分:0)

基于列表理解和groupby的方法,该方法将所有拆分的数据帧存储在列表变量中,并且可以使用索引进行访问。

示例:

ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]***
ans[0]
ans[0].column_name

答案 8 :(得分:0)

def split_and_save_df(df, name, size, output_dir):
    """
    Split a df and save each chunk in a different csv file.

    Parameters:
        df : pandas df to be splitted
        name : name to give to the output file
        size : chunk size
        output_dir : directory where to write the divided df
    """
    import os
    for i in range(0, df.shape[0],size):
        start  = i
        end    = min(i+size-1, df.shape[0]) 
        subset = df.loc[start:end] 
        output_path = os.path.join(output_dir,f"{name}_{start}_{end}.csv")
        print(f"Going to write into {output_path}")
        subset.to_csv(output_path)
        output_size = os.stat(output_path).st_size
        print(f"Wrote {output_size} bytes")