将dataframe分成多个dataframe
我有一个非常大的数据框(大约100万行),来自一个实验(60个受访者)的数据。 我想将dataframe分成60个dataframe(每个参与者的dataframe)。
在数据框(叫做= data)中有一个名为'name'的variables,它是每个参与者的唯一代码。
我已经尝试了以下,但没有发生(或一小时内不停止)。 我打算做的是将数据框(数据)拆分成更小的数据框,并将其附加到列表(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
我没有收到错误信息,脚本似乎永远运行!
有一个聪明的方法来做到这一点?
首先你的方法是低效的,因为逐行附加到列表将是缓慢的,因为当新条目没有足够的空间时,它必须周期性地增长列表,在这个方面列表理解更好,因为大小被确定前面分配一次。
不过,我认为从根本上说,你的方法有点浪费,因为你已经有了一个数据框,为什么要为每个用户创build一个新的呢?
我会按列'name'
sorting数据框,将索引设置为这个,如果需要的话不要删除列。
然后生成所有唯一条目的列表,然后可以使用这些条目执行查找,关键是如果只查询数据,则使用select条件返回dataframe的视图,而不会产生昂贵的数据副本。
所以:
# sort the dataframe df.sort(columns=['name'], 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'
我可以问为什么不通过切片数据框来做到这一点。 就像是
#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]
嘿presto你有一个数据框的字典就像(我想)你想要他们。 需要访问一个? 只要input
DataFrameDict['Joe']
希望有所帮助
Groupby可以帮助您:
grouped = data.groupby(['name'])
然后,您可以像每个参与者的数据框一样处理每个组。 而DataFrameGroupBy等对象方法(apply,transform,aggregate,head,first,last)则返回一个DataFrame对象。
或者你可以使列表从grouped
并通过索引获取所有DataFrame的:
l_grouped = list(grouped) l_grouped[0][1]
– 第一个名字为DataFrame的组。
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
除了Gusev Slava的回答,你可能想使用groupby的组:
{key: df.loc[value] for key, value in df.groupby("name").groups.items()}
这将产生一个字典,你已经分组的键,指向相应的分区。 优点是键维护,不要在列表索引中消失。
您可以将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 ABC 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 ABC 2 b 4 9 5 3 b 5 4 7, 'e': Name ABC 4 e 5 2 1, 'a': Name ABC 0 a 4 7 1 1 a 5 8 3, 'f': Name ABC 5 f 4 3 0} print (d['a']) Name ABC 0 a 4 7 1 1 a 5 8 3