首页 > 解决方案 > 如何使用地图多处理熊猫数据框?

问题描述

所以我可以使用 map 函数进行多处理,但是当我添加另一个变量时它不起作用。

       name                                    url
0   camera1     http://x.x.x.x:83/mjpg/video.mjpg
1   camera2      http://x.x.x.x:82/mjpg/video.mjpg
2   camera3     http://x.x.x.x:80/mjpg/video.mjpg
3   camera4  http://x.x.x.x:8001/mjpg/video.mjpg
4   camera5   http://x.x.x.x:8001/mjpg/video.mjpg
5   camera6     http://x.x.x.x:81/mjpg/video.mjpg
6   camera7     http://x.x.x.x:80/mjpg/video.mjpg
7   camera8     http://x.x.x.x:88/mjpg/video.mjpg
8   camera9     http://x.x.x.x:84/mjpg/video.mjpg
9  camera10      http://x.x.x.x:80/mjpg/video.mjpg

这是我的熊猫数据框。顺便说一句,我有实际的 IP。

下面的代码有效。我在子进程运行中只有 1 个变量。代码所做的是一次记录所有 http url。

camera_df = pd.read_csv('/home/test/streams.csv',low_memory=False)
def ffmpeg_function(*arg):
        subprocess.run(["/usr/bin/ffmpeg", "-y", "-t", "10", "-i", *arg, "-f", "null", "/dev/null"], capture_output=True)

p = mp.Pool(mp.cpu_count())
camera_df['url'] = p.map(ffmpeg_function, camera_df['url'])

但是当我尝试添加另一个变量来命名我正在录制的 mp4 文件时,它不起作用。我要做的是记录http url并在它旁边的列中的名称之后命名mp4文件

camera_df = pd.read_csv('/home/test/streams.csv',low_memory=False)
def ffmpeg_function(*arg):
        subprocess.run(["/usr/bin/ffmpeg", "-y", "-t", "10", "-i", *arg, *arg], capture_output=True)

p = mp.Pool(mp.cpu_count())
video_file = '/home/test/test.mp4'
camera_df['url'] = p.map(ffmpeg_function, [camera_df['url'], [camera_df['url']])

我在下面收到以下错误

TypeError: expected str, bytes or os.PathLike object, not Series

标签: pythonpython-3.xpandasffmpegmultiprocessing

解决方案


绝对没有充分的理由参与pandas其中。只需使用:

import multiprocessing as mp
import csv

def ffmpeg_function(args):
    result = subprocess.run(["/usr/bin/ffmpeg", "-y", "-t", "10", "-i", *args], capture_output=True)
    return result.stdout # not sure what you actually need...

with open('/home/test/streams.csv') as f, mp.Pool(mp.cpu_count()) as pool:
    reader = csv.reader(f)
    # skip header in csv
    next(reader)
    result = pool.map(ffmpeg_function, reader)

如果您坚持使用 pandas 来执行此操作,则只需使用itertuples

with mp.Pool(mp.cpu_count()) as pool:
    df = pd.read_csv('/home/test/streams.csv')
    df['whatever'] = pool.map(
        ffmpeg_function, 
        df.itertuples(index=False, name=None)
    )

有很多不同的方法可以做到这一点。

注意,在ffmep_function你必须实际返回一些东西。不完全确定你想要什么。return result.stdout.decode()如果你想要一个字符串而不是bytes对象,你可能想要使用。


推荐阅读