首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Shapely Multipoint转换为Pandas Dataframe的优雅方法

将Shapely Multipoint转换为Pandas Dataframe的优雅方法
EN

Stack Overflow用户
提问于 2021-06-30 00:07:10
回答 2查看 455关注 0票数 3

我需要将Shapely MultiPoints中的一条数据转换为数据格式。我已经编写了一个双循环程序来完成这个任务,但是我想知道是否有更好的方法来做到这一点。

样本数据和当前代码:

代码语言:javascript
复制
from shapely import wkb
import pandas as pd

data = {
    "A": "010400000002000000010100000000000000000008400000000000001440010100000000000000000008400000000000000840",
    "B": "01040000000200000001010000000000000000A061C00000000000A0894001010000000000000000708C400000000000C074C0",
    "C": "01040000000200000001010000000000000000EEB34000000000006CBB4001010000000000000000003E4000000000008DD3C0"
}

df = pd.DataFrame(columns=["ID", "X", "Y"])
for key, wkb_val in data.items():
    for point in wkb.loads(wkb_val, hex=True):
        df = df.append({
          "ID": key, "X": point.x, "Y": point.y  
        }, ignore_index=True)

这是有效的,如果有点缓慢和笨重。这能做得更好吗?如果是的话,怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-30 00:47:35

构建框架构造函数的列表理解可能是这里的最佳选择:

代码语言:javascript
复制
df = pd.DataFrame(
    [[k, point.x, point.y]
     for k, v in data.items()
     for point in wkb.loads(v, hex=True)],
    columns=['ID', 'X', 'Y']
)
代码语言:javascript
复制
  ID       X        Y
0  A     3.0      5.0
1  A     3.0      3.0
2  B  -141.0    820.0
3  B   910.0   -332.0
4  C  5102.0   7020.0
5  C    30.0 -20020.0

这里的pandas操作将是昂贵的,特别是循环中的append,它需要在每次迭代中生成DataFrame的副本。

通过%timeit提供的一些时间信息

这个答案

代码语言:javascript
复制
def fn(data):
    return pd.DataFrame(
        [[k, point.x, point.y]
         for k, v in data.items()
         for point in wkb.loads(v, hex=True)],
        columns=['ID', 'X', 'Y']
    )
代码语言:javascript
复制
%timeit fn(data)
552 µs ± 11.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

OP's solution

代码语言:javascript
复制
def fn2(data):
    df = pd.DataFrame(columns=["ID", "X", "Y"])
    for key, wkb_val in data.items():
        for point in wkb.loads(wkb_val, hex=True):
            df = df.append({
                "ID": key, "X": point.x, "Y": point.y
            }, ignore_index=True)
    return df
代码语言:javascript
复制
%timeit fn2(data)
10.3 ms ± 77.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Steele Farnsworth's Solution

代码语言:javascript
复制
def fn3(data):
    return pd.concat(
        (
            (
                pd.concat(
                    (pd.Series({"ID": key, "X": point.x, "Y": point.y}) for
                     point in
                     wkb.loads(wkb_val, hex=True)), axis=1)
            )
            for key, wkb_val in data.items()
        ), axis=1
    ).T
代码语言:javascript
复制
%timeit fn3(data)
3.42 ms ± 132 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
票数 4
EN

Stack Overflow用户

发布于 2021-06-30 00:25:02

性能缓慢的原因是,每次执行df = df.append(...)时,您都要创建一个新的DataFrame并复制所有现有的行。

这个解决方案看上去有点不可靠,但我相信它会奏效的。

代码语言:javascript
复制
df = pd.concat(
    (
        (
            pd.concat((pd.Series({"ID": key, "X": point.x, "Y": point.y}) for point in wkb.loads(wkb_val, hex=True)), axis=1)
        )
        for key, wkb_val in data.items()
    ), axis=1
).T

最后一个.T将转置DataFrame,否则将创建一个宽DataFrame,其中ID、X和Y作为索引,而不是列。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68186981

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档