如何解决对列表中所有可能的值对执行操作,对 Pandas DataFrame 中一行中的每个列表
我认识到这种嵌套方法并不是 Pandas 的真正工作方式,并且可能没有任何特别快速的解决方案,但我很感激任何帮助。
我有一个 Pandas DataFrame,其中一列包含整数列表。我想,对于每一行,找到此列表中的每一对(不相同,例如不是 (1,1)
)整数,并对其执行操作。这些列表的长度不一定相同。
额外的细节是每行包含一个 3D 顶点,这些整数是另一个 3D 顶点的 ID,存储在单独的 DataFrame 中。对于每一行,我想找到所有可能的命中对之间的角度,以行的顶点为原点,然后求平均值并做一些其他事情以获得“beta”。数学上非常简单,但我必须运行的行数很大,所以我想尽可能地加快速度。
我尝试了两种方法。
方法 1 - apply()
我采用的第一个(非矢量化)方法是使用一个单独的函数来获取行,为使用 itertools.combinations
生成的整数对创建一个新的 2 列 DataFrame。然后我使用连接来获取顶点信息并执行我的操作。然后我只使用 pd.DataFrame.apply()
。
这是没有实际计算的简化代码:
# Geometry df,map of id (cable) to vertex
geo = geo[["cable","x","y","z"]
def _beta_single(row):
# "cable" is the ID (integer)
cables = event["cable"]
pairs = [combo for combo in combinations(cables,2)]
pairs = pd.DataFrame(pairs,columns=["cable_1","cable_2"])
# Rename geo to have suffixes of vertex after merge
geo.columns = geo.columns.map(lambda x: str(x) + "_1")
# Get both hit locations
pairs = pairs.merge(geo,on="cable_1")
# Get rid of _1 suffix,add _2
geo.columns = geo.columns.map(lambda x: str(x)[:-2] + "_2")
pairs = pairs.merge(geo,on="cable_2")
# Perform calculations to get "beta" value (float)
row["beta"] = dostuff(pairs)
df = df.apply(_beta_single,axis=1)
这很慢。可能有一些优化可能会有所帮助,但对于 >100k 行、200C2 对,它看起来需要几个小时来处理。
方法 2 - 大量列
第二种方法是在 df 中为列表中的每个整数创建一个新列,如下所示:
nhits = df["cable"].str.len()
hit_cols = ["cable_%i" % (x+1) for x in range(max_nhits)]
# Convert cable column to list of lists
cable_lists = df["cable"].tolist()
# Make df of hits
df[hit_cols] = pd.DataFrame(cable_lists,index=df.index)
然后我再次使用 itertools.combinations
找到所有可能的组合,但这次是所有可能的列对,例如:
col_pairs = [combo for combo in combinations(range(1,(max_nhits+1)),2)]
并循环遍历这些,将成对中的列与顶点映射合并以获得两个顶点:
for col_pair in col_pairs:
# Column suffix
s1 = "_%i" % col_pair[0]
s2 = "_%i" % col_pair[1]
cables_1 = df["cable" + s1]
cables_2 = df["cable" + s2]
geo_1 = pd.merge(cables_1,geo,left_on=("cable" + s1),right_on="cable")
geo_2 = pd.merge(cables_2,left_on=("cable" + s2),right_on="cable")
beta = dostuff_vector(geo_1,geo_2)
抱歉我写了伪代码,但数学在这里并不重要,所以如果我省略它会更清楚。
这种方法肯定比另一种方法快,但对于方法 1 中提到的相同大小的 df,仍然需要半小时左右。
抱歉,帖子太长了,我只是想展示我已经玩过的东西。我想我正在寻找的是一个很好的矢量化 itertools 风格的东西。我曾想过有一列 itertools.combinations
对象,但您在嵌套迭代中遇到了麻烦。有人建议我以某种形式使用 groupby
之类的东西可能是最好的,但我不确定在这种情况下会是什么样子。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。