Fab*_*gio 5 python dataframe pandas
我有一个具有非连续索引的数据帧“工作”,这里是一个示例:
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
Run Code Online (Sandbox Code Playgroud)
我需要从此数据框中提取仅包含索引连续的行的新数据框,因此在这种情况下,我的目标是获取
DF_1.index=[4464,4465,4466]
DF_2.index=[5123,5124]
DF_3.index=[5323]
Run Code Online (Sandbox Code Playgroud)
维护所有列。
谁能帮我?谢谢!
groupby您可以使用以下方法制作完美的“连续”数组
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Run Code Online (Sandbox Code Playgroud)
如果我从单调增加的索引中减去此值,则只有那些“连续”的索引成员才会显示为相等。这是建立分组依据的聪明方法。
list_of_df = [d for _, d in df.groupby(df.index - np.arange(len(df)))]
Run Code Online (Sandbox Code Playgroud)
并打印每个证明
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
Run Code Online (Sandbox Code Playgroud)
np.split您可以使用np.flatnonzero来确定差异不相等的地方,1并避免使用cumsum和groupby
list_of_df = np.split(df, np.flatnonzero(np.diff(df.index) != 1) + 1)
Run Code Online (Sandbox Code Playgroud)
证明
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
Run Code Online (Sandbox Code Playgroud)
这是一个替代方案:
grouper = (~(pd.Series(df.index).diff() == 1)).cumsum().values
dfs = [dfx for _ , dfx in df.groupby(grouper)]
Run Code Online (Sandbox Code Playgroud)
我们使用一个事实,即连续的差值为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
Run Code Online (Sandbox Code Playgroud)
另一种看待它的方式是,我们寻找groupby的非序列,可能更易读:
non_sequence = pd.Series(df.index).diff() != 1
grouper = non_sequence.cumsum().values
dfs = [dfx for _ , dfx in df.groupby(grouper)]
Run Code Online (Sandbox Code Playgroud)