DAWorkbench 0.0.1
DAWorkbench API
载入中...
搜索中...
未找到
DAPySeries.h
1#ifndef DAPYSERIES_H
2#define DAPYSERIES_H
3#include "DAPyBindQtGlobal.h"
4#include "DAPyObjectWrapper.h"
5#include <QDebug>
6#include <QList>
7#include <QVariant>
8#include <QDateTime>
9#include "DAPybind11InQt.h"
10#include "DAPyIndex.h"
11
12namespace pybind11
13{
14class dtype;
15}
16namespace DA
17{
21class DAPYBINDQT_API DAPySeries : public DAPyObjectWrapper
22{
23public:
24 DAPySeries() = default;
25 DAPySeries(const DAPySeries& s);
27 DAPySeries(const pybind11::object& obj);
28 DAPySeries(pybind11::object&& obj);
30 // 操作符
31 DAPySeries& operator=(const pybind11::object& obj);
32 DAPySeries& operator=(const DAPySeries& s);
33 DAPySeries& operator=(const DAPyObjectWrapper& obj);
34 DAPySeries& operator=(pybind11::object&& obj);
35 DAPySeries& operator=(DAPySeries&& s);
36 DAPySeries& operator=(DAPyObjectWrapper&& obj);
37 pybind11::object operator[](std::size_t i) const;
38 // 如果索引是字符串,可以使用此函数
39 pybind11::object operator[](const QString& colName) const;
40
41public:
42 // 获取dtype
43 pybind11::dtype dtype() const;
44 // Series.empty
45 bool empty() const;
46 // Series.size
47 std::size_t size() const;
48 // Series.name
49 QString name() const;
50 // Series.iat
51 pybind11::object iat(std::size_t i) const;
52 void iat(std::size_t r, const pybind11::object& v);
53 //
54 QVariant value(std::size_t i) const;
55 bool setValue(std::size_t i, const QVariant& v);
56 // 类型判断
57 bool isNumeric() const;
58 bool isDateTime() const;
59 bool isString() const;
60 bool isCategorical() const;
61
62 // 索引相关
63 DAPyIndex index() const;
64 QStringList indexAsStringList() const;
65 QVector< double > indexAsDoubleVector() const;
66 QVector< QDateTime > indexAsDateTimeVector() const;
67 // 数据转换
68 DAPySeries astype(const pybind11::dtype& dt) const;
69 DAPySeries toDateTime() const;
70
71public:
72 // 判断是否为series
73 static bool isSeries(const pybind11::object& obj);
74 // 把series转换为一个容器数组
75 template< typename T, typename VectLikeIte >
76 void castTo(VectLikeIte begin) const;
77
78protected:
79 // 检测是否为dataframe,如果不是将会设置为none
80 void checkObjectValid();
81
82public:
83 // 转换为文本
84 QString toString(std::size_t maxele = 12) const;
85};
86
87DAPYBINDQT_API std::vector< double > toVectorDouble(const DA::DAPySeries& ser);
88DAPYBINDQT_API QVector< double > toQVectorDouble(const DA::DAPySeries& ser);
89
118template< typename T, typename VectLikeIte >
119void DAPySeries::castTo(VectLikeIte begin) const
120{
121 pybind11::object series = object(); // 当前 Series
122 pybind11::object values = series.attr("values"); // ndarray
123
124 // 检查是否是pandas Series
125 if (pybind11::isinstance(series, pybind11::module::import("pandas").attr("Series"))) {
126 pybind11::object dtype = series.attr("dtype");
127 std::string dtype_str = pybind11::str(dtype).cast< std::string >();
128
129 // 处理日期时间类型 (C++17兼容的方式)
130 if (dtype_str.find("datetime64") == 0) {
131 // 检查是否有时区信息
132 bool has_timezone = false;
133 try {
134 pybind11::object dt_accessor = series.attr("dt");
135 pybind11::object tz = dt_accessor.attr("tz");
136 has_timezone = !tz.is_none();
137 } catch (...) {
138 has_timezone = false;
139 }
140
141 if (has_timezone) {
142 // 有时区信息:先转换为UTC,再处理
143 pybind11::object dt_accessor = series.attr("dt");
144 pybind11::object utc_series = dt_accessor.attr("tz_convert")("UTC");
145 values = utc_series.attr("astype")("int64").attr("values");
146 } else {
147 // 没有时区信息:直接转换
148 values = series.attr("astype")("int64").attr("values");
149 }
150
151 // 转换时间戳到本地local
152 auto buf =
153 values.cast< pybind11::array_t< int64_t, pybind11::array::c_style | pybind11::array::forcecast > >();
154
155 std::transform(buf.data(), buf.data() + buf.size(), begin, [](int64_t ns) -> double {
156 qint64 utcMs = ns / 1'000'000;
157 return utcMs;
158 });
159 return;
160 }
161 // 处理时间增量类型 (timedelta)
162 else if (dtype_str.find("timedelta64") == 0) {
163 // 转成 int64 (nanoseconds)
164 values = series.attr("astype")("int64").attr("values");
165 // pybind11::object ts_local = series.attr("dt")
166 // .attr("tz_localize")(pybind11::none()) // 如果 naive,先声明为“本地”
167 // .attr("tz_convert")(pybind11::str("local")); // 有 tz 的也转到本地
168 // values = ts_local.attr("astype")("int64").attr("values");
169 // 将纳秒转换为秒
170 auto buf =
171 values.cast< pybind11::array_t< int64_t, pybind11::array::c_style | pybind11::array::forcecast > >();
172 std::transform(buf.data(), buf.data() + buf.size(), begin, [](int64_t ns) -> double {
173 return static_cast< double >(ns) / 1e9; // 纳秒转秒
174 });
175 return;
176 }
177 // 处理分类数据 (categorical)
178 else if (dtype_str.find("category") == 0) {
179 // 获取分类的代码
180 values = series.attr("cat").attr("codes").attr("values");
181 auto buf = values.cast< pybind11::array_t< T, pybind11::array::c_style | pybind11::array::forcecast > >();
182 std::copy(buf.data(), buf.data() + buf.size(), begin);
183 return;
184 }
185 // 处理布尔类型
186 else if (dtype_str == "bool") {
187 values = series.attr("astype")("int8").attr("values");
188 auto buf = values.cast< pybind11::array_t< int8_t, pybind11::array::c_style | pybind11::array::forcecast > >();
189 std::transform(buf.data(), buf.data() + buf.size(), begin, [](int8_t b) -> T { return static_cast< T >(b); });
190 return;
191 }
192 }
193
194 // 对于其他类型
195 auto buf = values.cast< pybind11::array_t< T, pybind11::array::c_style | pybind11::array::forcecast > >();
196 std::copy(buf.data(), buf.data() + buf.size(), begin);
197}
198} // namespace DA
199
200DAPYBINDQT_API QDebug operator<<(QDebug dbg, const DA::DAPySeries& ser);
201Q_DECLARE_METATYPE(DA::DAPySeries)
202#endif // DASERIES_H
对pandas.index的封装
Definition DAPyIndex.h:15
这是针对pubind11::object的封装
Definition DAPyObjectWrapper.h:15
pybind11::object attr(const char *c_att)
获取属性
Definition DAPyObjectWrapper.cpp:239
对Pandas.Series的Qt封装
Definition DAPySeries.h:22
pybind11::dtype dtype() const
Return the dtype object of the underlying data.
Definition DAPySeries.cpp:110
void castTo(VectLikeIte begin) const
把series转换为一个容器数组
Definition DAPySeries.h:119
序列化类都是带异常的,使用中需要处理异常
Definition AppMainWindow.cpp:44
std::vector< double > toVectorDouble(const DAPySeries &ser)
series 转换为vector< double >
Definition DAPySeries.cpp:386
QVector< double > toQVectorDouble(const DAPySeries &ser)
series 转换为QVector< double >
Definition DAPySeries.cpp:408