如何清理多列的 csv 数据?

问题描述 投票:0回答:1

我正在尝试帮助非营利组织进行一些数据分析。他们的电子表格如下所示:

“S1”代表传感器,有两个读数(温度和湿度),每天获取 3 次(6 12 6)。如何制作列来获取“S1”的数据,例如温度和湿度的每日平均值、每周平均值、每月平均值?我可能对这个有点不知所措。我可以使用 pandas 进行基本操作,但我不知道如何在“S1”的一个标题下组合列?非常感谢任何帮助。

这是我所知道的。不确定我是否走在正确的道路上?

pandas multiple-columns data-cleaning
1个回答
0
投票

你的数据框毕竟还不错。第 (2, 3) 行与第 7、11、15 行等只有一个例外。另一个小问题是时间:我假设时间是上午 6 点、中午 12 点和下午 6 点,因此需要将它们转换为 6、12 和 18采用 24 小时时间格式。如果我的假设正确并且您的屏幕截图不再包含异常,您可以像这样清理数据:

# Read data file without header/index and don't let pandas infers the dtype
df = pd.read_excel('data.xlsx', header=None, dtype=str)
m = df[1].notna()  # relevant rows (6, 12, 6)

# Create datetime index (rows)
dt = (pd.to_datetime(df[0].ffill() + ' ' + df[1], format='%d-%b-%y %H')
        .rename('DateTime')[m])
dt[2::3] += pd.DateOffset(hours=12)  # convert 6PM to 18

# Create multi-index headers (columns)
cols = df.loc[[0, 1]].ffill(axis=1).dropna(how='all', axis=1).T
mi = pd.MultiIndex.from_frame(cols, names=['Sensor', 'Metric'])

# Final output (remove two first columns)
out = df.loc[m, 2:].set_axis(dt, axis=0).set_axis(mi, axis=1).astype(float)

输出:

>>> out
Sensor                 S1          S2          S3      
Metric                  T     %     T     %     T     %
DateTime                                               
2023-08-01 06:00:00  30.3  87.0  29.4  86.0  29.5  65.0
2023-08-01 12:00:00  30.4  89.0  29.4  87.0  29.4  69.0
2023-08-01 18:00:00   NaN   NaN   NaN   NaN   NaN   NaN
2023-08-02 06:00:00  29.7  93.0  29.0  88.0  28.5  70.0
2023-08-02 12:00:00  29.5  93.0  28.8  88.0  28.4  70.0
2023-08-02 18:00:00  31.7  93.0  30.3  88.0  30.3  69.0
...

>>> out.index
DatetimeIndex(['2023-08-01 06:00:00', '2023-08-01 12:00:00',
               '2023-08-01 18:00:00', '2023-08-02 06:00:00',
               '2023-08-02 12:00:00', '2023-08-02 18:00:00'],
              dtype='datetime64[ns]', name='DateTime', freq=None)

>>> out.columns
MultiIndex([('S1', 'T'),
            ('S1', '%'),
            ('S2', 'T'),
            ('S2', '%'),
            ('S3', 'T'),
            ('S3', '%')],
           names=['Sensor', 'Metric'])

注意:要正确转换日期,您的区域设置必须是英语。由于我的语言环境是法语,我必须像这样切换到英语:

import locale
locale.setlocale(locale.LC_TIME, 'en_US.utf8')  # or 'C'
# 'en_US.utf8' is probably only valid on Linux and OSX, not Windows
© www.soinside.com 2019 - 2024. All rights reserved.