我有一个具有不连续索引的数据帧“工作”,这里是一个示例:
Index Column1 Column2
4464 10.5 12.7
4465 11.3 12.8
4466 10.3 22.8
5123 11.3 21.8
5124 10.6 22.4
5323 18.6 23.5
我需要从此数据框中提取仅包含索引连续的行的新数据框,因此在这种情况下,我的目标是获取
DF_1.index=[4464,4465,4466]
DF_2.index=[5123,5124]
DF_3.index=[5323]
维护所有列。
有人可以帮助我吗?谢谢!
答案 0 :(得分:5)
groupby
您可以使用以下方法制作完美的“连续”数组
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
如果我要从单调增加的索引中减去此值,则只有那些“连续”的索引成员才会显示为相等。这是建立分组依据的聪明方法。
list_of_df = [d for _, d in df.groupby(df.index - np.arange(len(df)))]
打印每一个以证明这一点
print(*list_of_df, sep='\n\n')
Column1 Column2
Index
4464 10.5 12.7
4465 11.3 12.8
4466 10.3 22.8
Column1 Column2
Index
5123 11.3 21.8
5124 10.6 22.4
Column1 Column2
Index
5323 18.6 23.5
np.split
您可以使用np.flatnonzero
来确定差异不等于1
的地方,并避免使用cumsum
和groupby
list_of_df = np.split(df, np.flatnonzero(np.diff(df.index) != 1) + 1)
证明
print(*list_of_df, sep='\n\n')
Column1 Column2
Index
4464 10.5 12.7
4465 11.3 12.8
4466 10.3 22.8
Column1 Column2
Index
5123 11.3 21.8
5124 10.6 22.4
Column1 Column2
Index
5323 18.6 23.5
答案 1 :(得分:4)
这里是替代方法:
grouper = (~(pd.Series(df.index).diff() == 1)).cumsum().values
dfs = [dfx for _ , dfx in df.groupby(grouper)]
我们使用这样一个事实,即连续差1等于一个序列(diff == 1)。
完整示例:
import pandas as pd
data = '''\
Index Column1 Column2
4464 10.5 12.7
4465 11.3 12.8
4466 10.3 22.8
5123 11.3 21.8
5124 10.6 22.4
5323 18.6 23.5
'''
fileobj = pd.compat.StringIO(data)
df = pd.read_csv(fileobj, sep='\s+', index_col='Index')
non_sequence = pd.Series(df.index).diff() != 1
grouper = non_sequence.cumsum().values
dfs = [dfx for _ , dfx in df.groupby(grouper)]
print(dfs[0])
# Column1 Column2
#Index
#4464 10.5 12.7
#4465 11.3 12.8
#4466 10.3 22.8
另一种看待它的方式是,我们寻找groupby的非序列,可能更易读:
non_sequence = pd.Series(df.index).diff() != 1
grouper = non_sequence.cumsum().values
dfs = [dfx for _ , dfx in df.groupby(grouper)]
答案 2 :(得分:0)
也许有一种更优雅的方式将其写下来,但这对我有用:
previous_index = df.index[0]
groups = {}
for x in df.index:
if (x-previous_index) ==1 :
groups[max(groups.keys())].append(x)
else:
groups[len(groups.keys())]=[x]
previous_index = x
output_dfs = []
for key, val in groups.items():
print(key, val)
output_dfs.append(df[df.index.isin(val)])
您的数据帧将存储在output_dfs
output_dfs[0].index
[4464,4465,4466]
答案 3 :(得分:0)
您可以使用exec创建多个数据框并获得预期的结果:
df = pd.DataFrame({'Column1' : [10.5,11.3,10.3,11.3,10.6,18.6], 'Column2' : [10.5,11.3,10.3,11.3,10.6,18.6]})
df.index = [4464, 4465, 4466, 5123, 5124, 5323]
prev_index = df.index[0]
df_1 = pd.DataFrame(df.iloc[0]).T
num_df = 1
for i in df.index[1:]:
if i == prev_index+1:
exec('df_{} = df_{}.append(df.loc[{}])'.format(num_df, num_df, i))
else :
num_df += 1
exec('df_{} = pd.DataFrame(df.loc[{}]).T'.format(num_df, i))
prev_index = i