Python中类似于Java Streams的管道操作

3

我主要使用Java编程,但是我觉得在数据分析方面Python更加方便。 我正在寻找一种类似于Java流的操作方式。例如,我想做类似于以下代码的操作(我混用了Java和Python语法)。

(key, value) = Files.lines(Paths.get(path))
   .map(line -> new Angle(line))
   .filter(angle -> foo(angle))
   .map(angle -> (angle, cosine(angle)))
   .max(Comparator.comparing(Pair::getValue)

在这里,我将从文件中提取一系列行,将每行转换为一个角度对象,通过某些参数过滤角度,然后创建一组成对的列表,并最终找到最大的一对。除此之外可能还有其他多个操作,但重点是这是一个管道,将一个操作的输出传递到下一个操作。
我知道Python列表推导式,但它们似乎仅限于单个“map”和单个“filter”。如果我需要使用推导式来连接多个映射,则表达式很快就会变得复杂(我需要将一个推导式放在另一个推导式内)。
在Python中是否有语法结构允许在一个命令中添加多个操作?

不过,您可以自定义一个新类来实现这一点。 - jizhihaoSAMA
1
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pipe.html,https://towardsdatascience.com/dplyr-style-data-manipulation-with-pipes-in-python-380dcb137000,https://towardsdatascience.com/the-flawless-pipes-of-python-pandas-30f3ee4dffc2 - user13963867
2个回答

4

自己实现并不困难,例如:

class BasePipe:
    def __init__(self, data):
        self.data = data
    
    def filter(self, f):
        self.data = [d for d in self.data if f(d)]
        return self
    
    def map(self, f):
        self.data = [*map(f, self.data)]
        return self
    
    def __iter__(self):
        yield from self.data
    
    def __str__(self):
        return str(self.data)
    
    def max(self):
        return max(self.data)

    def min(self):
        return min(self.data)

value = (
    BasePipe([1, 2, 3, 4]).
    map(lambda x: x * 2).
    filter(lambda x: x > 4).
    max()
)

并给出:

8

1
很遗憾,Python中没有内置的流(stream)功能,但是如果你想构建一个流水线,你可以使用PyStreamAPI。PyStreamAPI支持并行和顺序流(stream)。
以下是使用PyStreamAPI重写的代码:
from pystreamapi import Stream

with open("file.txt") as f:
    angle, cos = Stream.of(f.readlines()) \
        .map(lambda l: Angle(l))\
        .filter(lambda a: foo(a))\
        .map(lambda a: (a, cosine(a)))\
        .sorted(lambda a: Pair.getValue(a))\
        .max()

你可以在GitHub上查看完整的文档:https://github.com/PickwickSoft/pystreamapi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接