python - 处理我的测量数据的最佳库和实现
问题描述
我有很多测量数据要在 Python 中分析。每个数据集由一个参数集(带有数字、日期和字符串的标量)和两条曲线组成。
目标是能够过滤(根据标准选择)、分组、聚类、分析(例如,组中所有曲线和参数的平均值)和可视化数据集或它们的组。
我开始使用 Pandas 实现这一点,并创建了一个 Dataframe,其中每个参数都有一个列,测量 ID 作为索引。然后我为曲线添加了一列,使得该列中的每个字段都包含两条曲线作为两个 numpy 数组的字典。
这是一个示例实现(真实的数据框有数千个数据集和数十个参数列)
import numpy as np
import pandas as pd
example_dataset_nr = 5
# Column titles
columns = ['DateTime', 'PositionX', 'Filter', 'Curves']
# Generate arbitrary parameter data to fill example Dataframe
dates = [pd.Timestamp(i*10000000) for i in range(example_dataset_nr)]
positions = np.random.rand(example_dataset_nr)
filters = ['green']*example_dataset_nr
# Generate curves, such that each field in the Dataframes "Curves"-column contains
# a dict with two curves, each as a array of points:
curves = [{'curve_voltage': np.random.randint(0, 100, size=(100,2)), 'curve_current': np.random.randint(0, 100, size=(100))} for i in range(example_dataset_nr)]
# Create Dataframe
df = pd.DataFrame(data=np.array([dates, positions, filters, curves]).T, columns=columns)
df['PositionX'] = df['PositionX'].astype(np.float)
df.index.rename('MeasurementID', inplace=True)
print(df.to_string())
现在,如果我用“df.mean()”之类的操作分析数据,Pandas 当然不知道如何处理曲线。我希望 pandas 像在其他数字字段上一样对曲线进行操作。例如,假设 df.mean(),Pandas 应该计算所有曲线的平均值,而不仅仅是 Dataframe 中的参数。
# Get the mean of all numeric types. Want to get the mean curves of all 'curve_voltage' and 'curve_current', too.
df.mean()
我想知道,在 Python 中实现这种行为的最佳方式是什么?
以下是一些建议:
- Pandas:对曲线使用单独的数据框或系列,并通过外键将它们连接到纯“参数数据框”。但接下来的问题是如何自动将所有方法从“参数数据帧”转发到“曲线数据帧”而不重新实现它们?
- 熊猫:子类数据框。或任何其他扩展 Pandas 的方式。我阅读了https://pandas.pydata.org/pandas-docs/stable/development/extending.html,但我不确定哪个是正确的方法。再次以有意义的方式转发方法的相同问题。
- Xarray:我从未使用过它,但是 Xarray 是不是更适合我的需求的工具,然后是 pandas?
- 数据库:数据库是否更适合使用 SQL 之类的东西?
- 还有其他可行的选择吗?
解决方案
我认为这对于 xarray 来说是一个很好的用例,因为它自然支持将表格(一维)数据与更高维数据(你的曲线)结合起来。
使用 xarray,您可以像这样构建数据集:
import xarray as xr
ds = xr.Dataset(
{
'DateTime': (['MeasurementID'], dates),
'PositionX': (['MeasurementID'], positions),
'Filter': (['MeasurementID'], filters),
'curve_voltage': (['MeasurementID', 'curve_x', 'curve_y'], [row['curve_voltage'] for row in curves]),
'curve_current': (['MeasurementID', 'curve_x'], [row['curve_current'] for row in curves]),
},
coords={
'MeasurementID': np.arange(len(dates)),
'curve_x': np.arange(100),
'curve_y': np.arange(2)
}
)
并像这样使用它:
>>> ds
<xarray.Dataset>
Dimensions: (MeasurementID: 5, curve_x: 100, curve_y: 2)
Coordinates:
* MeasurementID (MeasurementID) int64 0 1 2 3 4
* curve_x (curve_x) int64 0 1 2 3 4 5 6 7 8 ... 92 93 94 95 96 97 98 99
* curve_y (curve_y) int64 0 1
Data variables:
DateTime (MeasurementID) datetime64[ns] 1970-01-01 ... 1970-01-01T00:00:00.040000
PositionX (MeasurementID) float64 0.7422 0.4789 0.7673 0.2552 0.8817
Filter (MeasurementID) <U5 'green' 'green' 'green' 'green' 'green'
curve_voltage (MeasurementID, curve_x, curve_y) int64 11 40 51 ... 38 26 64
curve_current (MeasurementID, curve_x) int64 88 24 57 32 75 ... 60 25 40 3
>>> ds['curve_voltage'].mean() # global average over all voltage curves
<xarray.DataArray 'curve_voltage' ()>
array(49.26)
>>> ds['curve_voltage'].mean('curve_x') # average only over curve_x dimension
ds['curve_voltage'].mean('curve_x')
<xarray.DataArray 'curve_voltage' (MeasurementID: 5, curve_y: 2)>
array([[47.06, 50.73],
[53.1 , 45.41],
[51.41, 50.33],
[49.12, 46.26],
[47.94, 51.24]])
Coordinates:
* MeasurementID (MeasurementID) int64 0 1 2 3 4
* curve_y (curve_y) int64 0 1
当然,您可以(并且应该)为附加维度指定比curve_x
和更有意义的名称curve_y
。
推荐阅读
- javascript - 更改时的角度选择值未更新
- python - 使用 Pandas 在列上提取文本中的子字符串
- google-cloud-platform - 谷歌语音到文本无法识别大量音频
- java - 使用Java在android studio中查询firebase数据库
- minikube - 如何调整 minikube vmdisk 的文件系统大小
- java - 如果我有很多锁更新哈希映射,我需要什么锁才能获得映射的最新值
- google-apps-script - 谷歌表格 - 根据 2 件事复制和粘贴数据,游戏编号和名称
- ruby - Ruby Hash.new 带块需要深入解释
- javascript - 尝试在 React.Js 中创建“返回主菜单”按钮
- apex - SOQL 帮助:如何在 apex SOQL 中获取正确的联系人 ID,我想将联系人 ID 分配到任务创建中的字段 whoid