Python 为什么这本词典理解得这么慢?请建议加快速度的方法

Python 为什么这本词典理解得这么慢?请建议加快速度的方法,python,pandas,list,list-comprehension,dictionary-comprehension,Python,Pandas,List,List Comprehension,Dictionary Comprehension,嗨,请帮助我:加快这本字典的压缩;提供一种更好的方法,或者更深入地理解为什么它在内部速度如此之慢(例如,随着字典内存大小的增加,计算速度会变慢)。我相信一定有一个更快的方法不用学C classes={i:[1如果df['column'].str.split(“|”)中的x为df['column']]i为df.index} 对于输出: {1:[0,1,0…0],…,4000:[0,1,1…0]} 从这样一个df: data_ = {'drugbank_id': ['DB06605', 'DB066

嗨,请帮助我:加快这本字典的压缩;提供一种更好的方法,或者更深入地理解为什么它在内部速度如此之慢(例如,随着字典内存大小的增加,计算速度会变慢)。我相信一定有一个更快的方法不用学C

classes={i:[1如果df['column'].str.split(“|”)中的x为df['column']]i为df.index}

对于输出:
{1:[0,1,0…0],…,4000:[0,1,1…0]}

从这样一个df:

data_ = {'drugbank_id': ['DB06605', 'DB06606', 'DB06607', 'DB06608', 'DB06609'], 
         'drug-interactions': ['DB06605|DB06695|DB01254|DB01609|DB01586|DB0212',
                               'DB06605|DB06695|DB01254|DB01609|DB01586|DB0212', 
                               'DB06606|DB06607|DB06608|DB06609', 
                               'DB06606|DB06607', 
                               'DB06608']
                             }

pd.DataFrame(data = data_  , index=range(0,5) )
我在一个有4000行的df中执行它,df列['column']包含一个由|分隔的id字符串。每行中需要拆分的ID数从1到1000不等,但是,所有4000个索引都需要拆分。我在df的头部测试了它,它看起来足够快,现在理解已经运行了24小时。因此,也许这只是工作的规模,但我觉得我可以加快速度,在这一点上,我想停止它的重新设计,然而,我害怕这将使我倒退,没有太多的速度增加,所以在我这样做之前,我想得到一些想法,想法和建议

除了4000x4000大小之外,我怀疑使用序列和索引对象是另一个问题,我最好使用列表,但考虑到任务的大小,我不确定这将获得多少速度,也许我最好使用其他方法,例如pd.apply(df,f(逐行写入json))。我不确定-感谢您的帮助和教育。

这里有一种方法:

import pandas as pd

# create data frame
df = pd.DataFrame({'idx': [1, 2, 3, 4], 'col': ['1|2', '1|2|3', '2|3', '1|4']})

# split on '|' to convert string to list
df['col'] = df['col'].str.split('|')

# explode to get one row for each list element
df = df.explode('col')

# create dummy ID (this will become True in the final result)
df['dummy'] = 1

# use pivot to create dense matrix
df = (df.pivot(index='idx', columns='col', values='dummy')
        .fillna(0)
        .astype(int))

# convert each row to a list
df['test'] = df.apply(lambda x: x.to_list(), axis=1)
print(df)

col  1  2  3  4          test
idx                          
1    1  1  0  0  [1, 1, 0, 0]
2    1  1  1  0  [1, 1, 1, 0]
3    0  1  1  0  [0, 1, 1, 0]
4    1  0  0  1  [1, 0, 0, 1]
以下是一种方法:

import pandas as pd

# create data frame
df = pd.DataFrame({'idx': [1, 2, 3, 4], 'col': ['1|2', '1|2|3', '2|3', '1|4']})

# split on '|' to convert string to list
df['col'] = df['col'].str.split('|')

# explode to get one row for each list element
df = df.explode('col')

# create dummy ID (this will become True in the final result)
df['dummy'] = 1

# use pivot to create dense matrix
df = (df.pivot(index='idx', columns='col', values='dummy')
        .fillna(0)
        .astype(int))

# convert each row to a list
df['test'] = df.apply(lambda x: x.to_list(), axis=1)
print(df)

col  1  2  3  4          test
idx                          
1    1  1  0  0  [1, 1, 0, 0]
2    1  1  1  0  [1, 1, 1, 0]
3    0  1  1  0  [0, 1, 1, 0]
4    1  0  0  1  [1, 0, 0, 1]

可以使用
假人
实现所需的输出。我们拆分列,
stack
,并使用
max
将其转换为基于原始索引的虚拟指示符。然后我们使用
reindex
根据
'drugbank\u id'
列按您想要的顺序获取它

最后,为了得到您想要的词典,我们将进行转置,并使用
进行dict

classes = (pd.get_dummies(df['drug-interactions'].str.split('|', expand=True).stack())
             .max(level=0)
             .reindex(df['drugbank_id'], axis=1)
             .fillna(0, downcast='infer')
             .T.to_dict('list'))

print(classes)
{0: [1, 0, 0, 0, 0],  #Has DB06605, No DB06606, No DB06607, No DB06608, No DB06609
 1: [1, 0, 0, 0, 0],
 2: [0, 1, 1, 1, 1],
 3: [0, 1, 1, 0, 0],
 4: [0, 0, 0, 1, 0]}

可以使用
假人
实现所需的输出。我们拆分列,
stack
,并使用
max
将其转换为基于原始索引的虚拟指示符。然后我们使用
reindex
根据
'drugbank\u id'
列按您想要的顺序获取它

最后,为了得到您想要的词典,我们将进行转置,并使用
进行dict

classes = (pd.get_dummies(df['drug-interactions'].str.split('|', expand=True).stack())
             .max(level=0)
             .reindex(df['drugbank_id'], axis=1)
             .fillna(0, downcast='infer')
             .T.to_dict('list'))

print(classes)
{0: [1, 0, 0, 0, 0],  #Has DB06605, No DB06606, No DB06607, No DB06608, No DB06609
 1: [1, 0, 0, 0, 0],
 2: [0, 1, 1, 1, 1],
 3: [0, 1, 1, 0, 0],
 4: [0, 0, 0, 1, 0]}

看起来您在每次迭代中都不必要地对整个列进行字符串拆分。您能提供一些示例数据和预期输出吗?我敢肯定,你可以得到一个解决方案,使这只需要几秒钟,也许最多一分钟。你为什么要“预制”一个“包含一串ID”的“df”?为什么不使用
集合
或其他更合适的数据结构呢?等待24小时表明你做错了什么!4k视频的像素数是所有数据的一半以上,播放视频意味着每秒处理30次帧。您应该能够相对容易地在100倍的范围内获得Python,也就是说@ALollz说几秒钟不应该是一个简单的时间problem@ALollz谢谢,我添加了一些示例数据。argh好的,谢谢哈哈,我没有意识到这一点,但这是有意义的,所以我需要使用df.iloc[df.index==i].str.split()在单元格级别进行拆分。哈哈,一分钟就好了sweet@SamMason谢谢,我想可能是没有经验吧。我会记住你的4K类比。3个小时后,它仍然在运行,所以只是让它过夜,它仍然没有完成。id对应于与给定id交互的id,它们将是唯一的,但在df单元中,它们当前是一个字符串。您认为我应该在df之外执行此操作吗?看起来您在每次迭代中都不必要地拆分整个列。您能提供一些示例数据和预期输出吗?我敢肯定,你可以得到一个解决方案,使这只需要几秒钟,也许最多一分钟。你为什么要“预制”一个“包含一串ID”的“df”?为什么不使用
集合
或其他更合适的数据结构呢?等待24小时表明你做错了什么!4k视频的像素数是所有数据的一半以上,播放视频意味着每秒处理30次帧。您应该能够相对容易地在100倍的范围内获得Python,也就是说@ALollz说几秒钟不应该是一个简单的时间problem@ALollz谢谢,我添加了一些示例数据。argh好的,谢谢哈哈,我没有意识到这一点,但这是有意义的,所以我需要使用df.iloc[df.index==i].str.split()在单元格级别进行拆分。哈哈,一分钟就好了sweet@SamMason谢谢,我想可能是没有经验吧。我会记住你的4K类比。3个小时后,它仍然在运行,所以只是让它过夜,它仍然没有完成。id对应于与给定id交互的id,它们将是唯一的,但在df单元中,它们当前是一个字符串。你认为我应该在df之外做这件事吗?谢谢@ALollz,在虚拟数据上做得很好,但是当我在实际df上尝试它时,会得到一个错误结果,如下所示,对此有什么想法吗?I cython#u操作(self、kind、values、how、axis、min_count、**kwargs)491#我们使用iNaT作为ints 492上缺少的值#因此预转换以保护此条件-->493 if(values==iNaT)。any():494 values=sure_float64(values)495 else:AttributeError:“bool”对象没有属性“any”@抱歉,在完成之前保存了最新的回溯是:cython_操作(自我、种类、值、方式、轴、最小计数,**kwargs)491#我们使用iNaT作为int 492上缺少的值#因此,如果(values==iNaT).any():494 values=确保\u float64(values)495 else:AttributeError:'bool'对象没有属性'any'对不起,我