gpt4 book ai didi

python - 当一个列表的所有元素都在另一个列表中时如何分组和求和

转载 作者:太空宇宙 更新时间:2023-11-04 09:31:09 25 4
gpt4 key购买 nike

我有一个数据框 df1。 “交易”列有一个 int 数组。

id     transactions
1 [1,2,3]
2 [2,3]

数据框 df2。 “items”列有一个 int 数组。

items  cost
[1,2] 2.0
[2] 1.0
[2,4] 4.0

我需要检查项目的所有元素是否都在每笔交易中,如果是的话,总结成本。

预期结果

id    transaction score
1 [1,2,3] 3.0
2 [2,3] 1.0

我做了以下

#cross join
-----------
def cartesian_product_simplified(left, right):
la, lb = len(left), len(right)
ia2, ib2 = np.broadcast_arrays(*np.ogrid[:la,:lb])

return pd.DataFrame(
np.column_stack([left.values[ia2.ravel()],
right.values[ib2.ravel()]]))

out=cartesian_product_simplified(df1,df2)

#column names assigning
out.columns=['id', 'transactions', 'cost', 'items']

#converting panda series to list
t=out["transactions"].tolist()
item=out["items"].tolist()


#check list present in another list
-------------------------------------
def check(trans,itm):
out_list=list()
for row in trans:
ret =np.all(np.in1d(itm, row))
out_list.append(ret)
return out_list

if true: group and sum
-----------------------
a=check(t,item)
for i in a:
if(i):
print(out.groupby(['id','transactions']))['cost'].sum()
else:
print("no")

抛出 TypeError:'NoneType' 对象不可订阅。

我是 python 的新手,不知道如何将所有这些放在一起。一个列表的所有项目在另一个列表中时如何分组并求和成本?

最佳答案

最简单的方法就是检查所有交易的所有项目:

# df1 and df2 are initialized

def sum_score(transaction):
score = 0
for _, row in df2.iterrows():
if all(item in transaction for item in row["items"]):
score += row["cost"]
return score

df1["score"] = df1["transactions"].map(sum_score)

在大规模上会非常慢。如果这是一个问题,我们不需要遍历每个项目,而是只预选可能的项目。如果你有足够的内存,它可以这样做。对于每个项目,我们都记住它出现的 df2 中的所有行号。因此,对于每笔交易,我们都会获取项目,获取所有可能的行并仅检查它们。

import collections

# df1 and df2 are initialized

def get_sum_score_precalculated_func(items_cost_df):

# create a dict of possible indexes to search for an item
items_search_dict = collections.default_dict(set)
for i, (_, row) in enumerate(items_cost_df.iterrow()):
for item in row["items"]:
items_search_dict[item].add(i)

def sum_score(transaction):
possible_indexes = set()
for i in transaction:
possible_indexes += items_search_dict[i]

score = 0
for i in possible_indexes:
row = items_cost_df.iloc[i]
if all(item in transaction for item in row["items"]):
score += row["cost"]
return score

return sum_score

df1["score"] = df1["transactions"].map(get_sum_score_precalculated_func(df2))

这里我用set 是唯一值的无序存储(它有助于连接可能的行号并避免重复计数)。collections.defaultdict 这是一个普通的 dict,但如果您尝试访问未初始化的值,它会用给定的数据填充它(空白 set我的情况)。它有助于避免 if x not in my_dict: my_dict[x] = set()。我还使用了所谓的“闭包”,这意味着 sum_score 函数将可以访问 items_cost_dfitems_search_dict,它们可以在 级别访问>sum_score 函数在返回和 get_sum_score_precalculated_func

后仍被声明

如果项目非常独特并且只能在 df2 的几行中找到,那应该会快得多。

如果您有很多独特的元素和很多相同的交易,您最好先计算每个独特交易的分数。然后加入结果。

transactions_score = []
for transaction in df1["transactions"].unique():
score = sum_score(transaction)
transaction_score.append([transaction, score])
transaction_score = pd.DataFrame(
transaction_score,
columns=["transactions", "score"])
df1 = df1.merge(transaction_score, on="transactions", how="left")

这里我使用第一个代码示例中的sum_score

附言对于 python 错误消息,应该有一个行号,这对理解问题有很大帮助。

关于python - 当一个列表的所有元素都在另一个列表中时如何分组和求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55703303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com