将 Dataframe 拆分为多个 Dataframe

6xfqseft  于 2021-09-13  发布在  Java
关注(0)|答案(11)|浏览(418)

我有一个非常大的数据框(大约100万行),其中包含来自一个实验(60名受访者)的数据。
我想将 Dataframe 拆分为60个 Dataframe (每个参与者一个 Dataframe )。
在 Dataframe 中, data ,有一个变量称为 'name' ,这是每个参与者的唯一代码。
我尝试了以下方法,但没有发生任何事情(或者执行不会在一小时内停止)。我打算做的是把这两份文件分开 data 放入较小的 Dataframe 中,并将其附加到列表中( datalist ):

import pandas as pd

def splitframe(data, name='name'):

    n = data[name][0]

    df = pd.DataFrame(columns=data.columns)

    datalist = []

    for i in range(len(data)):
        if data[name][i] == n:
            df = df.append(data.iloc[i])
        else:
            datalist.append(df)
            df = pd.DataFrame(columns=data.columns)
            n = data[name][i]
            df = df.append(data.iloc[i])

    return datalist

我没有收到错误消息,脚本似乎永远在运行!
有没有聪明的方法?

sigwle7e

sigwle7e1#

容易的:

[v for k, v in df.groupby('name')]
q9yhzks0

q9yhzks02#

groupby可以帮助您:

grouped = data.groupby(['name'])

然后,您可以处理每个组,就像处理每个参与者的 Dataframe 一样。和dataframegroupby对象方法,例如(apply、transform、aggregate、head、first、last)返回dataframe对象。
或者你可以从中列出清单 grouped 并按索引获取所有 Dataframe :

l_grouped = list(grouped)
``` `l_grouped[0][1]` -第一个名为的组的 Dataframe 。
vptzau2j

vptzau2j3#

除了gusev slava的答案之外,您可能还需要使用groupby的组:

{key: df.loc[value] for key, value in df.groupby("name").groups.items()}

这将生成一个字典,其中包含您分组所依据的键,指向相应的分区。这样做的好处是键被维护,并且不会在列表索引中消失。

ergxz8rk

ergxz8rk4#

In [28]: df = DataFrame(np.random.randn(1000000,10))

In [29]: df
Out[29]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000000 entries, 0 to 999999
Data columns (total 10 columns):
0    1000000  non-null values
1    1000000  non-null values
2    1000000  non-null values
3    1000000  non-null values
4    1000000  non-null values
5    1000000  non-null values
6    1000000  non-null values
7    1000000  non-null values
8    1000000  non-null values
9    1000000  non-null values
dtypes: float64(10)

In [30]: frames = [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]

In [31]: %timeit [ df.iloc[i*60:min((i+1)*60,len(df))] for i in xrange(int(len(df)/60.) + 1) ]
1 loops, best of 3: 849 ms per loop

In [32]: len(frames)
Out[32]: 16667

这里有一个groupby(您可以任意应用,而不是求和)

In [9]: g = df.groupby(lambda x: x/60)

In [8]: g.sum()    

Out[8]: 
<class 'pandas.core.frame.DataFrame'>
Int64Index: 16667 entries, 0 to 16666
Data columns (total 10 columns):
0    16667  non-null values
1    16667  non-null values
2    16667  non-null values
3    16667  non-null values
4    16667  non-null values
5    16667  non-null values
6    16667  non-null values
7    16667  non-null values
8    16667  non-null values
9    16667  non-null values
dtypes: float64(10)

总和是cythonized这就是为什么这是如此之快

In [10]: %timeit g.sum()
10 loops, best of 3: 27.5 ms per loop

In [11]: %timeit df.groupby(lambda x: x/60)
1 loops, best of 3: 231 ms per loop
fdx2calv

fdx2calv5#

基于列表理解和分类的方法 groupby -它将所有拆分的 Dataframe 存储在列表变量中,并且可以使用索引进行访问。
例子

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

ans[0]
ans[0].column_name
s71maibg

s71maibg6#

首先,op中的方法可行,但效率不高。因为数据集很长,所以它似乎一直在运行。
使用 .groupby'method' 列,并创建一个 dict 属于 DataFrames 独特的 'method' 值作为键,使用 dict-comprehension . .groupby 返回一个 groupby 对象,该对象包含有关组的信息,其中 g 这是唯一的价值 'method' 对于每组,以及 dDataFrame 那一组。
这个 valuekey 在里面 df_dict ,将是一个 DataFrame ,可通过标准方式访问, df_dict['key'] .
最初的问题需要一个答案 list 属于 DataFrames ,这可以通过
list-comprehension df_list = [d for _, d in df.groupby('method')] ```
import pandas as pd
import seaborn as sns # for test dataset

load data for example

df = sns.load_dataset('planets')

display(df.head())

        method  number  orbital_period   mass  distance  year

0 Radial Velocity 1 269.300 7.10 77.40 2006
1 Radial Velocity 1 874.774 2.21 56.95 2008
2 Radial Velocity 1 763.000 2.60 19.84 2011
3 Radial Velocity 1 326.030 19.40 110.62 2007
4 Radial Velocity 1 516.220 10.50 119.47 2009

Using a dict-comprehension, the unique 'method' value will be the key

df_dict = {g: d for g, d in df.groupby('method')}

print(df_dict.keys())
[out]:
dict_keys(['Astrometry', 'Eclipse Timing Variations', 'Imaging', 'Microlensing', 'Orbital Brightness Modulation', 'Pulsar Timing', 'Pulsation Timing Variations', 'Radial Velocity', 'Transit', 'Transit Timing Variations'])

or a specific name for the key, using enumerate (e.g. df1, df2, etc.)

df_dict = {f'df{i}': d for i, (g, d) in enumerate(df.groupby('method'))}

print(df_dict.keys())
[out]:
dict_keys(['df0', 'df1', 'df2', 'df3', 'df4', 'df5', 'df6', 'df7', 'df8', 'df9'])
``` df_dict['df1].head(3)df_dict['Astrometry'].head(3) 这一组只有两个

method  number  orbital_period  mass  distance  year
113  Astrometry       1          246.36   NaN     20.77  2013
537  Astrometry       1         1016.00   NaN     14.98  2010
``` `df_dict['df2].head(3)` 或 `df_dict['Eclipse Timing Variations'].head(3)` ```
method  number  orbital_period  mass  distance  year
32  Eclipse Timing Variations       1         10220.0  6.05       NaN  2009
37  Eclipse Timing Variations       2          5767.0   NaN    130.72  2008
38  Eclipse Timing Variations       2          3321.0   NaN    130.72  2008
``` `df_dict['df3].head(3)` 或 `df_dict['Imaging'].head(3)` ```
method  number  orbital_period  mass  distance  year
29  Imaging       1             NaN   NaN     45.52  2005
30  Imaging       1             NaN   NaN    165.00  2007
31  Imaging       1             NaN   NaN    140.00  2004

有关seaborn数据集的更多信息
nasa系外行星

或者

这是一种手动方法,用于创建单独的 DataFrames 使用Pandas:布尔索引
这与公认的答案相似,但是 .loc 不需要。
这是一种可以接受的方法,用于创建两个额外的 DataFrames .
创建多个对象的python方法是将它们放置在一个容器中(例如。 dict , list , generator 等),如上图所示。

df1 = df[df.method == 'Astrometry']
df2 = df[df.method == 'Eclipse Timing Variations']
wwtsj6pe

wwtsj6pe7#

如果已经有了一些数据标签,则可以使用groupby命令。

out_list = [group[1] for group in in_series.groupby(label_series.values)]

下面是一个详细的示例:
假设我们想使用一些标签将一个pd系列划分为一个区块列表,例如, in_series 是:

2019-07-01 08:00:00   -0.10
2019-07-01 08:02:00    1.16
2019-07-01 08:04:00    0.69
2019-07-01 08:06:00   -0.81
2019-07-01 08:08:00   -0.64
Length: 5, dtype: float64

及其相应的 label_series 是:

2019-07-01 08:00:00   1
2019-07-01 08:02:00   1
2019-07-01 08:04:00   2
2019-07-01 08:06:00   2
2019-07-01 08:08:00   2
Length: 5, dtype: float64

out_list = [group[1] for group in in_series.groupby(label_series.values)]

返回 out_list A. list 两个人 pd.Series :

[2019-07-01 08:00:00   -0.10
2019-07-01 08:02:00   1.16
Length: 2, dtype: float64,
2019-07-01 08:04:00    0.69
2019-07-01 08:06:00   -0.81
2019-07-01 08:08:00   -0.64
Length: 3, dtype: float64]

请注意,您可以从中使用一些参数 in_series 自身对系列进行分组,例如。, in_series.index.day

krcsximq

krcsximq8#

我也有类似的问题。我有10家不同商店和50种不同商品的每日销售时间序列。我需要将原始 Dataframe 拆分为500个 Dataframe (10个存储*50个存储),以便将机器学习模型应用到每个 Dataframe 中,但我无法手动执行。
这是 Dataframe 的头部:

我创建了两个列表;一个用于 Dataframe 的名称,另一个用于数组的耦合[项目编号,存储编号]。

list=[]
    for i in range(1,len(items)*len(stores)+1):
    global list
    list.append('df'+str(i))

    list_couple_s_i =[]
    for item in items:
          for store in stores:
                  global list_couple_s_i
                  list_couple_s_i.append([item,store])

一旦这两个列表准备好,您就可以循环使用它们来创建所需的 Dataframe :

for name, it_st in zip(list,list_couple_s_i):
                   globals()[name] = df.where((df['item']==it_st[0]) & 
                                                (df['store']==(it_st[1])))
                   globals()[name].dropna(inplace=True)

通过这种方式,我创建了500个 Dataframe 。
希望这将是有益的!

5t7ly7z5

5t7ly7z59#

首先,您的方法是低效的,因为逐行添加到列表会很慢,因为当没有足够的空间容纳新条目时,它必须周期性地增加列表。在这方面,列表理解更好,因为大小是预先确定并分配一次的。
然而,我认为基本上你的方法有点浪费,因为你已经有了一个 Dataframe ,那么为什么要为每个用户创建一个新的 Dataframe 呢?
我将按列对 Dataframe 进行排序 'name' ,将索引设置为此,如果需要,请不要删除该列。
然后生成所有唯一项的列表,然后可以使用这些项执行查找,最重要的是,如果只查询数据,则使用选择条件在 Dataframe 上返回视图,而不会产生昂贵的数据拷贝。
使用 pandas.DataFrame.sort_valuespandas.DataFrame.set_index :


# sort the dataframe

df.sort_values(by='name', axis=1, inplace=True)

# set the index to be this and don't drop

df.set_index(keys=['name'], drop=False,inplace=True)

# get a list of names

names=df['name'].unique().tolist()

# now we can perform a lookup on a 'view' of the dataframe

joe = df.loc[df.name=='joe']

# now you can query all 'joes'
tpgth1q7

tpgth1q710#

我可以问一下,为什么不直接对 Dataframe 进行切片呢。差不多


# create some data with Names column

data = pd.DataFrame({'Names': ['Joe', 'John', 'Jasper', 'Jez'] *4, 'Ob1' : np.random.rand(16), 'Ob2' : np.random.rand(16)})

# create unique list of names

UniqueNames = data.Names.unique()

# create a data frame dictionary to store your data frames

DataFrameDict = {elem : pd.DataFrame for elem in UniqueNames}

for key in DataFrameDict.keys():
    DataFrameDict[key] = data[:][data.Names == key]

嘿,普雷斯托,你有一个 Dataframe 字典,就像(我想)你想要的那样。需要访问一个吗?进来

DataFrameDict['Joe']

希望有帮助

vddsk6oq

vddsk6oq11#

你可以转换 groupby 反对 tuples 然后去 dict :

df = pd.DataFrame({'Name':list('aabbef'),
                   'A':[4,5,4,5,5,4],
                   'B':[7,8,9,4,2,3],
                   'C':[1,3,5,7,1,0]}, columns = ['Name','A','B','C'])

print (df)
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3
2    b  4  9  5
3    b  5  4  7
4    e  5  2  1
5    f  4  3  0

d = dict(tuple(df.groupby('Name')))
print (d)
{'b':   Name  A  B  C
2    b  4  9  5
3    b  5  4  7, 'e':   Name  A  B  C
4    e  5  2  1, 'a':   Name  A  B  C
0    a  4  7  1
1    a  5  8  3, 'f':   Name  A  B  C
5    f  4  3  0}

print (d['a'])
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3

不建议这样做,但可以按组创建 Dataframe :

for i, g in df.groupby('Name'):
    globals()['df_' + str(i)] =  g

print (df_a)
  Name  A  B  C
0    a  4  7  1
1    a  5  8  3

相关问题