计算Pandas系列坐标的平均值

dnph8jn4  于 10个月前  发布在  其他
关注(0)|答案(2)|浏览(93)

我有一个这样的Pandas系列,名字place

0    [[[1,2], [3,4], [5,6], [7,8]]]
1    [[[3,2], [6,4], [7,6], [2,8]]]
2    nan
...

字符串
每行的元素是盒子的顶点的坐标。
我想找到盒子的中心,保持nan的值,因为我想把这个系列连接到一个点阵,我需要相同的行数。
我最初的想法是写一个函数来计算平均值:

def centroid(arr_val):
    if arr_val:
        center = np.mean(np.array(arr_val[0]), axis=0)
    else:
        center = arr_val
    return center


并将其应用于级数的每个元素:

place.apply(lambda x: centroid(x))


但是我对这个系列中的列表的尺寸有一些问题,因为它是一个列表的列表的列表。
我想要的是:

0   [4., 5.]
1   [4.5, 5. ]
2   nan
...


有什么建议吗?

roejwanj

roejwanj1#

你的问题不是列表的尺寸,而是你没有正确地检查输入是否是nan。即使arr_valnan,你的测试也通过了:

arr_val = np.nan
if arr_val:
    print('nan is truthy')

字符串
打印nan is truthy。参见Why do "Not a Number" values equal True when cast as boolean in Python/Numpy?
改变你的测试--给定你的数据,可能最简单的只是检查一个列表--将解决你的问题:

def centroid(arr_val):
    if isinstance(arr_val, list):
        center = np.mean(np.array(arr_val[0]), axis=0)
    else:
        center = arr_val
    return center

place = pd.Series([
    [[[1,2], [3,4], [5,6], [7,8]]],
    [[[3,2], [6,4], [7,6], [2,8]]],
    np.nan
])
place.apply(centroid)


输出量:

0    [4.0, 5.0]
1    [4.5, 5.0]
2           NaN
dtype: object

fykwrbwg

fykwrbwg2#

IIUC,你可以构建Polygon s(* 如果有的话 *),然后计算geopandas提供的centroid

import geopandas as gpd
from shapely.geometry import Polygon

ser = place.str[0].dropna().apply(Polygon)

out = (gpd.GeoSeries(ser).centroid
           .apply(lambda p: list(map(
        lambda v: round(v, 1), (p.x, p.y)))) # optional ?
           .reindex_like(place)
      )

字符串
一个变种与纯shapely ',使用其centroid

from shapely.geometry import Polygon

out = (place.str[0].dropna().apply(
    lambda x: [round(Polygon(x).centroid.x, 1),
               round(Polygon(x).centroid.y, 1)])
           .reindex_like(place)
)


输出量:

print(out)

0    [4.0, 5.0]
1    [4.2, 5.2]
2           NaN
Length: 3, dtype: object


使用的输入:

place = pd.Series([
    [[[1, 2], [3, 4], [5, 6], [7, 8]]],
    [[[3, 2], [6, 4], [7, 6], [2, 8]]],
    pd.NA
    ]
)

相关问题