Python:如何根据第一列中的值将 pandas DataFrame 拆分为子集?

标签 python pandas dataframe

我有一个很大的实验日志文件 (.txt)(最多包含 100 000 个条目),其结构如下:

ROUTINE    TEMPERATURE    VOLTAGE    WAVELENGTH
_______________________________________________
CHANGE T   75             0          560
CHANGE T   80             0          560
CHANGE T   85             0          560
CHANGE T   90             0          560
OSL        75             20         570
OSL        75             20         580
OSL        75             20         590
OSL        75             20         600
CHANGE T   75             0          560
CHANGE T   80             0          560
CHANGE T   85             0          560
CHANGE T   90             0          560

我使用 pandasread_table 将日志文件加载到 python 中。我想根据第一列的值将生成的数据帧分成更小的数据帧。所以结果看起来像这样:

**DATAFRAME 1:**    
CHANGE T   75             0          560
CHANGE T   80             0          560
CHANGE T   85             0          560
CHANGE T   90             0          560

**DATAFRAME 2:** 
OSL        75             20         570
OSL        75             20         580
OSL        75             20         590
OSL        75             20         600

**DATAFRAME 3:** 
CHANGE T   75             0          560
CHANGE T   80             0          560
CHANGE T   85             0          560
CHANGE T   90             0          560

首先,我尝试使用第一列值发生变化的索引拆分它们:

indexSplit = [] # list containing the boundry indices

prevRoutine = log['ROUTINE'][0] # log is the complete dataframe
i = 1
while i < len(log):
        if prevRoutine != log['ROUTINE'][i]:
            indexSplit.append(i)
        prevRoutine = log['ROUTINE'][i]

然而,考虑到日志文件的大小,以这种方式(显然)需要花费大量时间。我想知道是否有一种优雅的方法可以用 Pandas 做到这一点?我一直遇到的问题是第一列的值在多个系列中使用。我总是以 dataframe 1dataframe 3 作为一个结束。

最佳答案

您可以使用 list comprehension,其中循环 groupby 对象和 groupss 创建。比较 ne (与 != 相同,但速度更快)shift编辑专栏和 cumsum获取输出:

s = df['ROUTINE'].ne(df['ROUTINE'].shift()).cumsum()
print (s)
0     1
1     1
2     1
3     1
4     2
5     2
6     2
7     2
8     3
9     3
10    3
11    3
Name: ROUTINE, dtype: int32

dfs = [g for i,g in df.groupby(df['ROUTINE'].ne(df['ROUTINE'].shift()).cumsum())]
print (dfs)
[    ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
0  CHANGE T           75        0         560
1  CHANGE T           80        0         560
2  CHANGE T           85        0         560
3  CHANGE T           90        0         560,   ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
4     OSL           75       20         570
5     OSL           75       20         580
6     OSL           75       20         590
7     OSL           75       20         600,      ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
8   CHANGE T           75        0         560
9   CHANGE T           80        0         560
10  CHANGE T           85        0         560
11  CHANGE T           90        0         560]

print (dfs[0])
    ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
0  CHANGE T           75        0         560
1  CHANGE T           80        0         560
2  CHANGE T           85        0         560
3  CHANGE T           90        0         560

print (dfs[1])
  ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
4     OSL           75       20         570
5     OSL           75       20         580
6     OSL           75       20         590
7     OSL           75       20         600

print (dfs[2])
     ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
8   CHANGE T           75        0         560
9   CHANGE T           80        0         560
10  CHANGE T           85        0         560
11  CHANGE T           90        0         560

解决方案很复杂,因为如果对第一列使用 groupby 只能得到 2 组:

dfs = [g for i,g in df.groupby('ROUTINE')]
print (dfs)
[     ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
0   CHANGE T           75        0         560
1   CHANGE T           80        0         560
2   CHANGE T           85        0         560
3   CHANGE T           90        0         560
8   CHANGE T           75        0         560
9   CHANGE T           80        0         560
10  CHANGE T           85        0         560
11  CHANGE T           90        0         560,   ROUTINE  TEMPERATURE  VOLTAGE  WAVELENGTH
4     OSL           75       20         570
5     OSL           75       20         580
6     OSL           75       20         590
7     OSL           75       20         600]

关于Python:如何根据第一列中的值将 pandas DataFrame 拆分为子集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41144231/

相关文章:

python - django 和 mongodb 是否使迁移成为过去?

python - 替换 Pandas 数据框中的值(不包括缺失值)

python - 从 Webscrape 中过滤和格式化数据帧

python - 根据其他列的值填充 Pandas 列的简单方法

python - 常见的 lisp 格式指令来打印列表

python - 对字典进行排序但出现 "List Indices must be int, not tuple"错误

python - 通过 pandas 坐标数据框查找单元格中的点

python - 如何在 Python 中使用 Pandas 从 s3 存储桶中读取 csv 文件

python - 循环 e​​xcel 文件,再添加一列并用 Python 保存

r - 如何对数据进行分组和合并