为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Pandas DataFrame 计算列表字典?

如何使用 Pandas DataFrame 计算列表字典?

千巷猫影 2021-06-04 17:12:27
我在 Python3.x 中有两个字符串,它们被定义为相同的长度:string1 = 'WGWFTSJKPGP'string2 = 'DORKSRQKYJG'我还得到了一个整数,用于表示string2. 在这种情况下,start_pos = 51。目标是根据索引创建字典。所以,string1始于0,string2始于51。字典“转换”这些坐标如下:{0: 51, 1: 52, 2: 53, 3: 54, 4: 55, 5: 56, 6: 57, 7: 58, 8: 59, 9: 60, 10: 61}可以用以下方法构造(给出上面的变量):convert_dict = {i: i + start_pos for i, _ in enumerate(string1)}我目前以 Pandas DataFrame 的形式拥有这些数据:import pandas as pddict1 = {'column1':['MXRBMVQDHF', 'LJNVTJOY', 'LJNVTJOY', 'LJNVTJOY', 'WHLAOECVQR'], 'column2':['DPBVNJYANX', 'UWRAWDOB', 'PEKUYUQR', 'WPMLFVFZ', 'CUTQVWHRIJ'], 'start':[79, 31, 52, 84, 18]}df = pd.DataFrame(dict1)print(df)#       column1     column2  start# 0  MXRBMVQDHF  DPBVNJYANX     79# 1    LJNVTJOY    UWRAWDOB     31# 2    LJNVTJOY    PEKUYUQR     52# 3    LJNVTJOY    WPMLFVFZ     84# 4  WHLAOECVQR  CUTQVWHRIJ     18column 中有多个相同字符串的条目column1。在这种情况下,坐标的字典LJNVTJOY应该是:{0: [31, 52, 84], 1: [32, 53, 85], 2: [33, 54, 86], 3: [34, 55, 87],      4: [35, 56, 88], 5: [36, 57, 89], 6: [37, 58, 90], 7: [38, 59, 91]}我想使用这个 DataFrame 并计算坐标的类似字典。这样的.groupby('column1')声明看起来应该以某种方式使用.apply()? 我不知道如何填充这样的字典列表......这是正确的输出(保持 DataFrame 结构)。此处 DataFramedf2具有如下所示的列'new_column':df2.new_column0    {0: 79, 1: 80, 2: 81, 3: 82, 4: 83, 5: 84, 6: ...1    {0: [31, 52, 84], 1: [32, 53, 85], 2: [33, 54, 86], 3: [34, 55, 87], 4: [35, 56, 88], 5: [36, 57, 89], 6: [37, 58, 90], 7: [38, 59, 91]}2    {0: 52, 1: 53, 2: 54, 3: 55, 4: 56, 5: 57, 6: ...Name: new, dtype: object
查看完整描述

3 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

用 -


def dict_op(x):

    string1 = x['column1']

    string2 = x['column2']

    start_pos = x['start']

    x['val'] = {i: i + start_pos for i, _ in enumerate(string1)}

    return x


def zip_dict(x):

    b=pd.DataFrame(x)

    return {i:b.loc[:,i].tolist() for i in b.columns }


op = df.apply(dict_op, axis=1).groupby('column1')['val'].apply(list).apply(zip_dict)

print(op)

输出


column1

LJNVTJOY      {0: [31, 52, 84], 1: [32, 53, 85], 2: [33, 54,...

MXRBMVQDHF    {0: [79], 1: [80], 2: [81], 3: [82], 4: [83], ...

WHLAOECVQR    {0: [18], 1: [19], 2: [20], 3: [21], 4: [22], ...

Name: val, dtype: object

解释


该dict_op重用你的代码创建的每一行的字典,然后.apply(list)将拉链类型的字典在一起,形成类型的字典列表。


在zip_dict()随后创建输出dict了临时的输出。


我没有包含的最后一部分是如果列表的长度为 1 那么你可以只包含第一个元素的部分,将输出从{0: [79], 1: [80], 2: [81], 3: [82], 4: [83], ...到{0: 79, 1: 80, 2: 81, 3: 82, 4: 83, ...


查看完整回答
反对 回复 2021-06-09
?
PIPIONE

TA贡献1829条经验 获得超9个赞

首先应用 groupby 函数将“开始”列聚合为列表


df2 = df.groupby("column1")["start"].apply(list).reset_index()

现在,您可以编写一个函数来创建新的字典列


def create_dict(row):

    new_dict = {}

    for i, j in enumerate(row["column1"]):

        if len(row["start"]) == 1:

            new_dict[i] = row["start"][0]+i

        else:

            for k in row["start"]:

                if i in new_dict:

                    new_dict[i].append(k + i)

                else:

                    new_dict[i] = [k + i]

    return new_dict

最后,将此函数应用于 df2 的所有行


df2["new_column"] = df2.apply(create_dict, axis = 1)


查看完整回答
反对 回复 2021-06-09
?
杨魅力

TA贡献1811条经验 获得超6个赞

这是使用 alambda和 two的略有不同的方法zips。


df2 = df.groupby('column1')['start'].agg([('s', list)]).reset_index()

df2['l'] = df.column1.str.len()


df2.apply(lambda x: dict(zip(range(x['l'] + 1), zip(*[range(s, s + x['l'] + 1) for s in x['s']]))), axis = 1)

可以在此处看到截断的输出(请注意,它返回元组而不是列表):


0    {0: (31, 52, 84), 1: (32, 53, 85), 2: (33, 54,...

1    {0: (79,), 1: (80,), 2: (81,), 3: (82,), 4: (8...

2    {0: (18,), 1: (19,), 2: (20,), 3: (21,), 4: (2...

首先,为了减少apply步骤的长度,创建一个包含column1值和相关起始位置的 DataFrame 。另外,添加一个长度为column1(假设等长断言成立)的列。


之后,就是组合column1字母索引的范围(0通过len(column1),用作键,以及由start值偏移的相同范围)。


第二个事情变得有点冒险,zip因为[range(s, s + x['l'] + 1) for s in x['s']]返回看起来像这样的东西(对于'LJNVTJOY'):


[[31, 32, 33, 34, 35, 36, 37, 38, 39],

 [52, 53, 54, 55, 56, 57, 58, 59, 60],

 [84, 85, 86, 87, 88, 89, 90, 91, 92]]

当我们真的想对垂直对齐的元素进行分组时,我们使用“splat”或“ unpacking ”运算符将这些列表输入到zip. 一旦我们组合了这些列表,我们就有了一个键列表和一个值列表(元组),它们可以zipped放入dict.


查看完整回答
反对 回复 2021-06-09
  • 3 回答
  • 0 关注
  • 181 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号