跳到主要内容
版本:Next
pythonINPUTBUFFERPROCESSOROUTPUT

Python

Python 处理器通过 PyO3 对每个消息批次执行用户提供的 Python 代码。传入的 MessageBatch 会以 PyArrow RecordBatch 的形式暴露给你的函数,函数返回一个或多个 PyArrow 批次,这些批次再被转换回引擎的列式格式。借助 Python 的数据生态(PyArrow、Pandas、Polars、NumPy 等),你可以据此实现自定义变换。

配置​

FieldTypeRequiredDefault描述
typestringyes—python
scriptstringno—要执行的内联 Python 源码。提供时,代码会在所配置的模块中运行。
modulestringno__main__从中导入函数的 Python 模块。提供 script 时忽略此项。
functionstringyes—要调用的 Python 函数名。该函数必须接受一个 PyArrow 批次,并返回一个 PyArrow 批次列表。
python_patharray<string>no[]为模块导入而添加到 sys.path 的额外路径;靠前的条目优先级更高,已存在的条目不会重复添加,工作目录 . 排在配置路径之后。
timeout_msintegerno60000单次函数调用的耗时上界(毫秒)。超时使整批报错而不是无限阻塞流;被放弃的 Python 调用仍会在其线程上运行至自然返回。全进程最多 64 个 UDF 调用在运行(或挂起)——超出者等待,避免卡死的调用耗尽共享阻塞线程池。

示例​

使用 Python 模块​

- type: "python"
function: "process_batch"
module: "example1"
python_path: ["./examples/python"]

使用内联 Python 脚本​

- type: "python"
script: |
def process_batch(batch):
# Process the batch here
# For example, you can modify the batch or create a new one
return [batch]
function: "process_batch"

完整流水线示例​

streams:
- input:
type: "memory"
messages:
- '{ "timestamp": 1625000000000, "value": 10, "sensor": "temp_1" }'
- '{ "timestamp": 1625000000000, "value": 19, "sensor": "temp_1" }'
- '{ "timestamp": 1625000000000, "value": 11, "sensor": "temp_2" }'
- '{ "timestamp": 1625000000000, "value": 11, "sensor": "temp_2" }'

pipeline:
thread_num: 4
processors:
- type: "json_to_arrow"
- type: "python"
script: |
import pyarrow as pa
import pyarrow.compute as pc

def process_batch(batch):
value_array = batch.column('value')
doubled_values = pc.multiply(value_array, 2)
new_fields = [
pa.field('timestamp', pa.int64()),
pa.field('value', pa.int64()),
pa.field('sensor', pa.string()),
pa.field('value_doubled', pa.int64())
]
new_schema = pa.schema(new_fields)
new_batch = pa.RecordBatch.from_arrays(
[
batch.column('timestamp'),
batch.column('value'),
batch.column('sensor'),
doubled_values
],
schema=new_schema
)
return [new_batch]
function: "process_batch"
- type: "arrow_to_json"

output:
type: "stdout"

Python 模块示例​

def process_batch(batch):
# The batch parameter is a PyArrow batch
# You can perform any processing on the batch here
# For example, you can modify the batch or create a new one
return [batch] # Return a list of PyArrow batches

说明​

PyArrow 数据处理示例​

下面的代码片段展示了可以在你的 Python 函数中使用的常见数据处理模式。

数据过滤​

def filter_data(batch):
import pyarrow as pa
import pyarrow.compute as pc

value_array = batch.column('value')
mask = pc.greater(value_array, 15)
filtered_batch = batch.filter(mask)

return [filtered_batch]

数据变换​

def transform_data(batch):
import pyarrow as pa
import pyarrow.compute as pc

value_array = batch.column('value')
doubled_values = pc.multiply(value_array, 2)
squared_values = pc.power(value_array, 2)

new_fields = [
pa.field('timestamp', pa.int64()),
pa.field('value', pa.int64()),
pa.field('sensor', pa.string()),
pa.field('value_doubled', pa.int64()),
pa.field('value_squared', pa.int64())
]
new_schema = pa.schema(new_fields)
new_batch = pa.RecordBatch.from_arrays(
[
batch.column('timestamp'),
batch.column('value'),
batch.column('sensor'),
doubled_values,
squared_values
],
schema=new_schema
)

return [new_batch]

数据聚合​

def aggregate_data(batch):
import pyarrow as pa
import pandas as pd

df = batch.to_pandas()
aggregated = df.groupby('sensor').agg({
'value': ['mean', 'min', 'max', 'sum', 'count']
}).reset_index()
aggregated.columns = ['sensor', 'value_mean', 'value_min', 'value_max', 'value_sum', 'value_count']
result_batch = pa.RecordBatch.from_pandas(aggregated)

return [result_batch]

时间序列处理​

def process_timeseries(batch):
import pyarrow as pa
import pandas as pd

df = batch.to_pandas()
df['datetime'] = pd.to_datetime(df['timestamp'], unit='ms')
df.set_index('datetime', inplace=True)
df['value_ma'] = df['value'].rolling('5s').mean()
df['value_change'] = df['value'].pct_change()
df.reset_index(inplace=True)
result_batch = pa.RecordBatch.from_pandas(df)

return [result_batch]

将一个批次拆分为多个批次​

def split_data(batch):
import pyarrow.compute as pc

value_array = batch.column('value')
high_values_mask = pc.greater_equal(value_array, 50)
low_values_mask = pc.less(value_array, 50)

high_values_batch = batch.filter(high_values_mask)
low_values_batch = batch.filter(low_values_mask)

return [high_values_batch, low_values_batch]

使用 Polars 进行高性能数据操作​

Polars 是一个用 Rust 实现的快速 DataFrame 库,它以 Apache Arrow 列式格式作为内存模型,对于较大的数据集来说是 Pandas 的高性能替代选择。

def aggregate_with_polars(batch):
import polars as pl

df = pl.from_arrow(batch)
aggregated_df = df.group_by("sensor").agg([
pl.col("value").mean().alias("value_mean"),
pl.col("value").min().alias("value_min"),
pl.col("value").max().alias("value_max"),
pl.col("value").sum().alias("value_sum"),
pl.col("value").count().alias("value_count"),
])
result_batch = aggregated_df.to_arrow()

return [result_batch]