我有一个非常大的数据框(大约100万行),包含来自实验的数据(60位受访者)。 我想将数据帧拆分为60个数据帧(每个参与者的数据帧)。
在数据框(称为= data)中有一个名为'name'的变量,它是每个参与者的唯一代码。
我尝试过以下操作,但没有任何反应(或者在一小时内没有停止)。我打算做的是将数据帧(数据)拆分成更小的数据帧并将它们附加到列表(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
我没有收到错误消息,脚本似乎永远都会运行!
有没有聪明的方法呢?
答案 0 :(得分:50)
我可以问为什么不通过切片数据框来做到这一点。像
这样的东西#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]
嘿,你有一个数据框架字典就像(我认为)你想要它们一样。需要访问一个?只需输入
即可DataFrameDict['Joe']
希望有所帮助
答案 1 :(得分:39)
首先,你的方法是低效的,因为在新的条目没有足够的空间时,必须定期增加列表,因此逐行附加到列表中的速度会很慢,因此列表推导在这方面更好预先确定并分配一次。
但是,我认为从根本上说你的方法有点浪费,因为你已经拥有了一个数据帧,为什么要为每个用户创建一个新的数据框?
我会按列'name'
对数据框进行排序,将索引设置为此值,如果需要则不删除列。
然后生成所有唯一条目的列表,然后您可以使用这些条目执行查找,并且至关重要的是,如果您只查询数据,请使用选择标准返回数据框上的视图,而不会产生代价高昂的数据副本。 / p>
所以:
# 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'
sort
现已弃用,您现在需要使用sort_values
:
# 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'
答案 2 :(得分:31)
您可以将groupby
对象转换为selenium.common.exceptions.WebDriverException: Message: Unable to find a matching set of capabilities
,然后转换为tuples
:
dict
它不是recommended,但可以按组创建DataFrame:
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
答案 3 :(得分:11)
Groupby可以帮助您:
grouped = data.groupby(['name'])
然后,您可以使用每个参与者的数据框来处理每个组。而DataFrameGroupBy对象方法(如apply,transform,aggregate,head,first,last)返回一个DataFrame对象。
或者您可以从grouped
制作列表,并按索引获取所有DataFrame:
l_grouped = list(grouped)
l_grouped[0][1]
- 具有名字的第一个组的DataFrame。
答案 4 :(得分:7)
简单:
[v for k, v in df.groupby('name')]
答案 5 :(得分:4)
除了Gusev Slava的回答,您可能还想使用groupby的小组:
element.all(by.css('.settings__group .settings__sub-title')).count().then(function(count)
{
for(var j = 0; j < count;j++)
{
console.log('first loop ' + j);
browser.sleep(2000);
element.all(by.className('settings__group')).get(j).all(by.className('settings__item')).count().then(function (c) {
for (let i = 0; i < c; i++) {
console.log('second loop ' + i);
browser.sleep(1000);
element.all(by.className('settings__group')).get(j).all(by.className('settings__item')).get(i).click();
browser.sleep(1000);
element(by.id('crValidationButton')).isPresent().then(function (present) {
if (present) {
element(by.id('crValidationButton')).click();
browser.sleep(2000);
v.validationCase();
browser.sleep(2000);
}
else {
browser.sleep(2000);
v.validationCase();
browser.sleep(2000);
}
});
browser.sleep(1500);
}
});
}
});
这将产生一个字典,其中包含您分组的键,指向相应的分区。优点是密钥保持不变并且不会在列表索引中消失。
答案 6 :(得分:3)
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)
Sum是cython化的,这就是为什么这么快
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
答案 7 :(得分:1)
基于列表理解和groupby
的方法-将所有拆分数据帧存储在列表变量中,并且可以使用索引进行访问。
示例
ans = [pd.DataFrame(y) for x, y in DF.groupby('column_name', as_index=False)]
ans[0]
ans[0].column_name
答案 8 :(得分:1)
'method'
列上使用.groupby
,并使用唯一的dict
值作为键,并创建一个DataFrames
的{{1}},其中{{3} }。
'method'
返回一个.groupby
对象,该对象包含有关组的信息,其中groupby
是g
中每个组的唯一值,而'method'
是该组的d
。DataFrame
中每个value
的{{1}}将是一个key
,可以通过标准方式df_dict
进行访问。DataFrame
中的df_dict['key']
,可以通过dict-comprehension
完成
list
DataFrames
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)
list-comprehension
的更多信息
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
不是必需的。DataFrames
的可接受方法。.loc
,DataFrames
,dict
等),如上所示。list
答案 9 :(得分:0)
如果您已经有一些数据标签,则可以使用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
和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
答案 10 :(得分:0)
这里有一个小函数,它可能对某些人有所帮助(效率可能不完美,但紧凑 + 或多或少容易理解):
def get_splited_df_dict(df: 'pd.DataFrame', split_column: 'str'):
"""
splits a pandas.DataFrame on split_column and returns it as a dict
"""
df_dict = {value: df[df[split_column] == value].drop(split_column, axis=1) for value in df[split_column].unique()}
return df_dict
它将一个 DataFrame 转换为多个 DataFrame,方法是选择给定列中的每个唯一值并将所有这些条目放入一个单独的 DataFrame 中。
.drop(split_column, axis=1)
仅用于删除用于拆分 DataFrame 的列。删除不是必需的,但可以帮助减少操作后的内存使用量。
get_splited_df_dict
的结果是 dict
,这意味着可以像这样访问每个 DataFrame:
splitted = get_splited_df_dict(some_df, some_column)
# accessing the DataFrame with 'some_column_value'
splitted[some_column_value]
答案 11 :(得分:-1)
我有类似的问题。我有10个不同商店和50个不同商品的每日销售时间序列。我需要将原始数据帧拆分为500个数据帧(10存储* 50存储),以将机器学习模型应用于每个模型,而我无法手动完成。
这是数据框的开头:
我创建了两个列表; 一个用于数据框的名称 一个用于两个数组[item_number,store_number]。
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])
两个列表准备好后,您可以在它们上循环创建所需的数据框:
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个数据帧。
希望这会有所帮助!