Home Php C# Sql C C++ Javascript Python Java Go Android Git Linux Asp.net Django .net Node.js Ios Xcode Cocoa Iphone Mysql Tomcat Mongodb Bash Objective-c Scala Visual-studio Apache Elasticsearch Jar Eclipse Jquery Ruby-on-rails Ruby Rubygems Android-studio Spring Lua Sqlite Emacs Ubuntu Perl Docker Swift Amazon-web-services Svn Html Ajax Xml Java-ee Maven Intellij-idea Rvm Macos Unix Css Ipad Postgresql Css3 Json Windows-server Vue.js Typescript Oracle Hibernate Internet-explorer Github Tensorflow Laravel Symfony Redis Html5 Google-app-engine Nginx Firefox Sqlalchemy Lucene Erlang Flask Vim Solr Webview Facebook Zend-framework Virtualenv Nosql Ide Twitter Safari Flutter Bundle Phonegap Centos Sphinx Actionscript Tornado Register | Login | Edit Tags | New Questions | 繁体 | 简体


10 questions online user: 12

12
votes
answers
16 views
+10

根据最大值的长度从python中找到项目列出的dictonary?

假设我有一个字典,如:

  dicl = {'amazon':[668,667,879],'flipkart':[678],'嘿':[89 ,79]}   

我想根据项目长度的降序打印字典项目。

我想要的输出:

  {'amazon':3,'hey':2,'flipkart':1}   < p>但是我按照项目的降序显示结果,而我想根据项目的降序显示项目? 

我尝试过:

  cov_m = {k:len(v)表示k,v表示已排序(dicl.items())}   

当前输出:

  {'amazon' :3,'flipkart'
    
        
沙发
+40
+50

您可以将 lambda 函数作为参数传递给 sorted 函数,以指定您的排序条件:

  dicl = { 'amazon':[668,667,879],'flipkart':[678],'hey':[89,79]} cov_m = {k:len(v)for k,v in sorted(dicl.items( ),key = lambda i:-len(i [1]))} print(cov_m)  

输出:

  {'amazon':3 ,'嘿':2,'flipkart':1}   

这里, len(i [1])是值的长度,我'我按 -len(i [1])(负长度)排序,因为你希望它们按降序排列,如果有更高级的排序标准,你应该使用,reverse = True)而不是。

谢谢Geek先生。假设我需要像这样保留项目细节:{'amazon':( [668,667,879],3),'hey':( [89,79],2),'flipkart':( [678] ,1)}。怎么做我尝试过这样的事情,但没有得到理想的结果。我尝试过{k [0]:(len(v))表示k,v表示已排序(dicl.items(),key = lambda x:len(x [1]),reverse = True)} - Mishra S 8月29日13:14

@MishraS只需在cov_m的定义中将k:len(v)改为k:(v,len(v))。 - MrGeek 8月29日13:17

+20

sorted 与自定义键一起使用。

例如:

  dicl = {'amazon':[ 668,667,879],'flipkart':[678],'嘿':[89,79]} print({k:len(v)表示k,v表示已排序(dicl.items(),key = lambda) x:len(x [1]),reverse = True)})  

输出:

  {'amazon' :3,'嘿':2,'flipkart':1}  
     
			
        
+20

我会将数据转换为排序列表:

  data = {'amazon':[668,667,879],'flipkart':[678],'嘿': [89,79]} sorted_data = sorted([{'name':k,'val':len(v)}代表k,v代表data.items()],key = lambda x:x ['val'] ,reverse = True)print(sorted_data)  

输出:

  [{'name':'amazon','val':3},{ 'name':'嘿','val':2},{'name':'flipkart','val':1}]  
     
			
        
+20

两个建议的答案都会在每个项目上调用 len()两次。为什么不叫它一次?(不是为了表现,而是为了冷静)

代码

  dicl = {'amazon':[668,667,879],'flipkart ':[678],'嘿':[89,79]} length_dict = {k:len(v)代表k,v代表dicl.items()}#在dict中的长度值上排序,使用长度的倒数为@MrGeek建议sorted_on_values = sorted(length_dict.items(),key = lambda d:-d [1])sorted_dict = dict(sorted_on_values)  

输出 < / p>

  {'amazon':3,'嘿':2,'flipkart':1}  
     
			
        
+20

你可以这样做

  dicl = {'amazon':[668,667,879],'flipkart':[678],'嘿':[89,79 ]} cov_m = {k:len(v)表示k,v表示已排序(dicl.items(),key = lambda x:x [1])}   

输出

  {'amazon':3,'嘿':2,'flipkart':1}  
     
			
        

只有在添加新的键值对时才需要保留顺序,才需要OrderedDict。在OP的情况下,他已经有一个他想要排序的填充字典。 - Sam Legesse 8月29日12:20

@SamLegesse你是对的,这就是为什么我给了两个解决方案。如果他想保留dict,那么可以使用OrderedDict。 - somil 8月29日12:56

或者如果你正在使用python 2 - Laurens Koppenol 8月29日12:56

15
votes
answers
22 views
+10

求和之间的值

目标:

每当密钥相同时,我都会尝试将dict ct_db和ct_db2之间的值相加。

例如:

RR-00 == RR-00,所以make 14 + 223

问题:

所有的dict键都没有被比较,一旦遍历dict就会终止操作,但由于键没有顺序,所以没有进行正确的计算。

SCRIPT:

  ct_db = {u'AB-00':18,u'RR-00':14,u'LD-00':56,u'SR-00':33 ,u'YT-00':452} ct_db2 = {u'CD-07':26,u'RR-00':223,u'LD-00':367,u'SR-00':257,你'IA-00':11} not_installed = []表示elemA,elemB表示zip(ct_db,ct_db2):if(elemA == elemB):print(“MATCH”+ elemA +“ - ”+ elemB)not_installed.append(ct_db [elemA] + ct_db2 [elemB])else:print(“NOT MATCH”+ elemA +“ - ”+ elemB)print(not_installed)  

OUTPUT: < pre> NOT MATCH LD-00 - CD-07 NOT MATCH SR-00 - LD-00 NOT MATCH AB-00 - RR-00 NOT MATCH RR-00 - IA-00 NOT MATCH YT-00 - SR-00 [] append(ct_db [elemA] + ct_db2 [elemB])else:print(“NOT MATCH”+ elemA +“ - ”+ elemB)print(not_installed)

OUTPUT:< / strong>

  NOT MATCH LD-00  -  CD-07 NOT MATCH SR-00  -  LD-00 NOT MATCH AB-00  -  RR-00 NOT MATCH RR-00  -  IA-00 NOT匹配YT-00  -  SR-00 []  append(ct_db [elemA] + ct_db2 [elemB])else:print(“NOT MATCH”+ elemA +“ - ”+ elemB)print(not_installed)  

OUTPUT:< / strong>

  NOT MATCH LD-00  -  CD-07 NOT MATCH SR-00  -  LD-00 NOT MATCH AB-00  -  RR-00 NOT MATCH RR-00  -  IA-00 NOT匹配YT-00  -  SR-00 []  
    
        
沙发
+30
+50

算法很简单:找到两个词典之间的公共密钥并计算总和。在Python 3中, dict.keys()方法返回一个类似于set的对象,因此我们可以使用&amp; 运算符来查找两组键之间的交集:

  ct_db = {u'AB-00':18,u'RR-00':14,u'LD-00':56,u'SR-00':33,u 'YT-00':452} ct_db2 = {u'CD-07':26,u'RR-00':223,u'LD-00':367,u'SR-00':257,u'IA -00':11} print(ct_db)print(ct_db2)common_keys = ct_db.keys()&amp; ct_db2.keys()not_installed = {k:ct_db [k] + ct_db2 [k] for k in common_keys} print(not_installed)  

输出:

  {'AB-00':
     
			
        
+50

你只需要遍历其中一个dicts的键,并检查每个键是否在另一个dict中:

  not_installed = []对于ct_db中的elem:if elem in ct_db2:not_installed.append(ct_db [elem] + ct_db2 [elem])print(not_installed)  

输出:

  [237,423,290]  
     
			
        

@ MrGeek的代码是正确的。如果某个密钥仅在ct_db2中,则不应对其进行计数。 - Hai Vu 7小时前

+30

在这种情况下,您可以使用集合的交集属性,例如 https:// howtodoinjava.com/python/dictionary-intersection/

  ct_db = {u'AB-00':18,u'RR- 00':14,u'LD-00':56,u'SR-00':33,u'YT-00':452} ct_db2 = {u'CD-07':26,u'RR-00' :223,u'LD-00':367,u'SR-00':257,u'IA-00':11} not_installed = [] ct_set = set(ct_db)ct_set2 =设置(ct_db2)ct_set中的名称.intersection(ct_set2):#print(name)查看公共密钥not_installed.append(ct_db [name] + ct_db2 [name])print(not_installed) 
     
			
        
+20

以下是使用 collections.Counter执行此操作的方法

  from collections import Counter ct_db = {u'AB-00':18,u'RR-00':14,u'LD-00' :56,u'SR-00':33,u'YT-00':452} ct_db2 = {u'CD-07':26,u'RR-00':223,u'LD-00':367 ,u'SR-00':257,u'IA-00':11} counter = collections.Counter(ct_db)counter + = ct_db2#&gt;&gt;&gt; counter#Counter({'YT-00':452,'LD-00':423,'SR-00':290,'RR-00':237,'CD-07':26,'AB-00' :18,'IA-00':11})#并且如果你只想要重叠键:overlapping_keys = ct_db.keys()&amp; ct_db2.keys()counter = {k:v表示k,v表示counter.items()如果k表示overlap_keys}#&gt;&gt;&gt; counter#{'RR-00':237,'LD-00':423,'SR-00':290}  
     
			
        
+20

使用字典理解是一种简洁的替代方法。

给出两个字典 d1 d2

 输出= {k:d1 [k] + d2 [k]表示d1.keys()&amp;中的k。d2.keys()}   

表达式 d1.keys()&amp; d2.keys()利用 dict_keys 对象上可用的 set 交集。

9
votes
answers
18 views
+10

如何查找在python中呈现一个列表而不是另一个列表的子列表?[重复]

我需要比较两个列表,这些列表基本上是list-of-list,找出一个列表中存在的子列表,而不是其他列表。此外,子列表的排列也不考虑即['a','b'] = ['b,'a']。这两个列表是

  List_1 = [['T_1','T_2'],['T_2','T_3'],['T_1','T_3']] List_2 = [ ['T_1','T_2'],['T_3','T_1']]   

输出列表应为

  out_list = [[ 'T_2','T_3']]   我需要比较两个列表,这些列表基本上是列表列表,找出列表中存在但不存在其他列表的子列表。此外,子列表的排列也不考虑即['a','b'] = ['b,'a']。这两个列表是 
  List_1 = [['T_1','T_2'],['T_2','T_3'],['T_1','T_3']] List_2 = [ ['T_1','T_2'],['T_3','T_1']]   

输出列表应为

  out_list = [[ 'T_2','T_3']]   我需要比较两个列表,这些列表基本上是列表列表,找出列表中存在但不存在其他列表的子列表。此外,子列表的排列也不考虑即['a','b'] = ['b,'a']。这两个列表是 
  List_1 = [['T_1','T_2'],['T_2','T_3'],['T_1','T_3']] List_2 = [ ['T_1','T_2'],['T_3','T_1']]   

输出列表应为

  out_list = [[ 'T_2','T_3']]  
    
        
沙发
+30

对于两个元素子列表,这应该足够了:

  [如果x不在List_2中,则x在List_1中为x而x [::  -  1]不在List_2中 < / pre> 

代码

  List_1 = [['T_1','T_2'],['T_2','T_3'],[' T_1','T_3']] List_2 = [['T_1','T_2'],['T_3','T_1']] print(如果x不在List_2和x [::  - 中,则x在List_1中为x 1]不在List_2]) 
     
			
        

这只能可靠地用于2个项目的子列表,但是roganjosh 8月31日10:53

@roganjosh,是的。已添加到我的答案中。:) - 奥斯汀8月31日10:54

所以我看到:)我认为我们可以做得更好,设置交叉点,但我需要在我脑海中充实一点。这将是两次扫描列表 - 罗根乔什8月31日10:56

这是一个2n ^ 2的解决方案(时间复杂度)? - rusu_ro1 8月31日12:55

板凳
+20

这是一个有点混乱的功能解决方案,在过程中使用 set tuple set s被使用因为你是什么尝试计算的是对称差异,并使用元组因为与 list 不同,它们是可以删除的,可以用作 set 元素):

  List_1 = [['T_1' ,'T_2'],['T_2','T_3'],['T_1','T_3']] List_2 = [['T_1','T_2'],['T_3','T_1']] f = lambda l:tuple(sorted(l))out_list = list(map(list,set(map(f,List_1))。symmetric_difference(map(f,List_2))))print(out_list)  

输出:

  [['T_2','T_3']] < /代码> 
     
			
        
地板
+20

我会说 frozensets 更适合这样的任务:

  fs2 = set(map(frozenset,List_2))out = set(map(frozenset,List_1))。symmetric_difference(fs2)print(out)#{frozenset({'T_2' ,'T_3'}}}   

这里使用 frozensets 的好处是可以对它们进行哈希处理,因此您可以简单地映射两个列表并采取 set.symmetric_difference


如果你想从输出中得到一个嵌套列表,你可以简单地做:

  list(map (列表,出))  

请注意,某些子列表可能以不同的顺序出现,但假设任务不应该是一个问题

嗯,是的,我认为你对@MrGeek - yatu 8月31日11:02

现在的问题是你没有得到一个列表输出,所以不管怎样,如果你完全遵循它将会看起来像MrGeek的答案 - roganjosh 8月31日11:08

是的,我的全部观点是使用套装或者冷冻套装可能只是更合适的@roganjosh。所以不确定OP想从这里做什么,但根据任务这可能会更有用 - yatu 8月31日11:09

请注意,如果顺序可以互换,为什么不使用集@roganjosh但是,如果输出必须是嵌套列表完全同意 - yatu 8月31日11:11

是的我知道你不是,只是暴露我的观点,同意:) @roganjosh - yatu 8月31日11:14

4楼
+10

如果你的列表中没有重复项,你可以使用:

  set(list_1中的e的frozenset(e)).symmetric_difference({list_2中的{frozenset(e)for e} )  

输出:

  {frozenset({'T_2','T_3'}),frozenset({1,2})}   

如果您需要列表作为输出,您可以使用:

  [list(o)for o in output]   < p> ouptut: 
  [['T_2','T_3']]  
     
			
        
5楼
+10
为了更好地了解每个答案的资源消耗和效率,我已经完成了一些测试希望最好选择。

对问题数据的结果:

用1k-10k-1000k进行测试怎么样,我确定顶部不会相同,3个元素的测试不那么相关 - rusu_ro1 8月31日12:42

@ rusu_ro1,当然。我添加了更大数据的测试。 - Olvin Roght 8月31日13:22

时间很有趣,但它不是一个公平的竞争环境。你可以在yatu的回答中看到我的评论; 它没有回馈清单。 - roganjosh 8月31日13:25

此外,奥斯汀的答案是不可扩展的。我怀疑你从你自己的答案的时间学到了一些东西,但是:) - roganjosh 8月31日13:27

@roganjosh,我已经更新了函数以返回相同的结果。关于我的回答 - 这对我来说并不意外。实际上,这是我添加测试的原因之一,因为我的解决方案看起来最紧凑但绝对不是最有效的;) - Olvin Roght 8月31日13:29

6楼
0
运算符是前者可以将任何可迭代作为其参数。这样可以避免将 map(frozenset,List_2)转换为集合,从而获得一些性能。
  out = [* map(list,{* map(frozenset,List_1) )}。symmetric_difference(map(frozenset,List_2)))]  
     
			
        
13
votes
answers
36 views
+10

在其他列为NaN的位置填写相同数量的字符

我有以下虚拟数据帧:

  df = pd.DataFrame({'Col1':['a,b,c,d','e,f,g,h ','i,j,k,l,m'],'Col2':['aa~bb~cc~dd',np.NaN,'ii~jj~kk~ll~mm']})Col1 Col2 0 a,b,c,d aa~bb~cc~dd 1 e,f,g,h NaN 2 i,j,k,l,m ii~jj~kk~ll~mm   

真实数据集的形状为 500000,90

我需要将这些值排除在行之外,而我正在使用新的 explode 这个方法很好。

问题是 NaN ,这些会在 explode 之后产生不等长度,所以我需要填写与填充相同数量的分隔符值。对于这个有更简单,更通用的方法吗?或者我的方法很好。

沙发
+30
+50

pd.concat
  delims = {'Col1':',','Col2':'?'} pd.concat({k:df [k] .str.split(delims [k],expand = True),其中k表示df},轴= 1).stack()Col1 Col2 0 0 a aa 1 b bb 2 c cc 3 d dd 1 0 e NaN 1 f NaN 2 g NaN 3 h NaN 2 0 i ii 1 j jj 2 k kk 3 l ll 4 m mm   

这在 df 中的列上循环。 delims 字典中循环键可能更明智。

  delims = {'Col1':',','Col2':'?'} pd .concat({k:df [k] .str.split(delims [k],expand = True)对于k中的delims},axis = 1).stack()  
<

这看起来与delims dict有关。让我测试一下,但这应该很容易维护,并且可以推广到更多列。 - Erfan 10小时前

+40

一种方法是使用 <代码> str.repeat fillna()不确定这是多么有效:

  df.Col2.fillna(pd。系列(['?'] * len(df))。str.repeat(df.Col1.str.count(',')))  
  0 aa~bb~cc~dd 1 ~~~ 2 ii~jj~kk~ll~mm名称:Col2,dtype:object  
     
			
        

谢谢,我可以用您的代码将两行替换为一行。 - Erfan 11小时前

+30

将数据帧拆分为两个

  df1 = df.dropna()df2 = df.drop(df1.index)d1 = df1 ['Col1']。str.split(' ,')。explode()d2 = df1 ['Col2']。str.split('?')。explode()d3 = df2 ['Col1']。str.split(',')。explode()final = pd.concat([d1,d2],axis = 1).append(d3.to_frame(),sort = False)Out [77]:Col1 Col2 0 a aa 0 b bb 0 c cc 0 d dd 2 i ii 2 j jj 2 k kk 2 l ll 2 m mm 1 e NaN 1 f NaN 1 g NaN 1 h NaN  
     
			
        

这最接近我想要的,问题是我有相当一些列 - Erfan 11小时前

+30
鉴于您不需要原始索引,

zip_longest 在此处非常有用。无论哪个列有更多分割,它都可以工作:

 来自itertools import zip_longest,chain df = pd.DataFrame({'Col1':['a,b,c,d',' e,f,g,h','i,j,k,l,m','x,y'],'Col2':['aa~bb~cc~dd',np.NaN,'ii~ jj~kk~ll~mm','xx~yy~zz']})#Col1 Col2#0 a,b,c,d aa~bb~cc~dd#1 e,f,g,h NaN#2 i,j,k,l,m ii~jj~kk~ll~mm#3 x,y xx~yy~zz   
  l = [zip_longest( zip中的x为* x,fillvalue ='')(df.Col1.str.split(',')。fillna(''),df.Col2.str.split('?')。fillna('
     
			
        

刚测试它并产生错误的输出,请检查示例中的第13,14,15行。 - Erfan 11小时前

也许我不够清楚,但如果你检查我的预期输出你就可以看到它。真实数据集是更改历史记录,其中第一列跟踪列名称,第二列记录值的更改。因此第一个值应该仅与第一行中的第一个值匹配。 - Erfan 10小时前

我尝试了一些编辑的解决方案,遗憾的是我无法获得正确的输出。 - Erfan 10小时前

是的,我想如果您需要保留ID或其他列,那将会很棘手。 - ALollz 10小时前

18
votes
answers
42 views
+10

如何根据索引名称的长度选择pandas系列行?

我有一个如下所示的熊猫系列,如何只选择索引长度大于3的行?

  s = pd.Series([1,2,3] ,4,5],index = ['a','bb','ccc','dddd','eeeee'])  

必需输出:

  dddd 4 eeeee 5   

我的尝试:

  s [len(s.index.name)&gt; 3]  
    
        
沙发
+50
+50

你可以试试:

  s [s.index.str.len()&gt; 3]给dddd 4 eeeee 5  
     
			
        
+50

使用列表理解:

  s [[len(i)&gt; 3 for s in s.index]]   

输出:

  dddd 4 eeeee 5 dtype:int64  
     
			
        

因为,你知道,为什么不... s [[* map(3 .__ lt __,map(len,s.index))]] - piRSquared 8月29日20:43

@piRSquared为什么连s [map(3 .__ lt __,map(len,s.index))] - rafaelc 8月29日20:47

因为...因为...我没有理由。哦!这是因为我没有意识到你可以传递一个地图对象。 - piRSquared 8月29日20:48

+40

使用 get

  s [s.index.str.get(3).notnull()]   
  dddd 4 eeeee 5 dtype:int64  
     
			
        
+40

我将通过 pandas.Series.filter 例程:

 在[216]中:s.filter(regex ='。{4, }')Out [216]:dddd 4 eeeee 5 dtype:int64   
  • '。{4,}' - 仅匹配标签的正则表达式模式(包含至少4个字符的索引)

    简化版本可能看起来像'。* 4 ....


很好地使用pandas.Series.filter - piRSquared 8月29日20:45

此外,如果你想打高尔夫球(不确定你为什么要这么做但是没有)s.filter(regex ='。'* 4) - piRSquared 8月29日21:03

@piRSquared,差异可以忽略不计,但是做一个替代方案很好(我们甚至可以做更简单的正则表达式''......')。我为这个技巧添加了一个表示法。谢谢 - RomanPerekhrest 8月30日9:07

15
votes
answers
24 views
+10

python字典keyError

python的新手,看起来像是一段简单的可操作代码,产生 KeyError

  patt = list('jkasb')dict = {} for i in patt:dict [i] = 1如果dict [i]为None否则dict [i] +1#此行抛出错误  

错误:KeyError:'j'

沙发
+70
+50

在您的情况下,KeyError正在发生,因为您正在尝试访问不在字典中的键。最初,字典是空的。因此,其中没有密钥存在。

如果您来自C ++背景,这可能看起来很奇怪,因为C ++地图为尚不存在的键提供了默认值。您可以使用 collections.defaultdict 在python中获得相同的行为。修改后的代码如下。我冒昧地将defaultdict转换为代码末尾的常规字典:

  from collections import defaultdict patt ='jkasb'my_default_dict = defaultdict(int)for i in patt:my_default_dict [i] + = 1 my_dict = dict(my_default_dict)#将defaultdict转换为常规字典  

您还可以通过许多其他方式解决此问题。我在下面展示其中一些:

  • 通过检查字典中是否存在密钥:

      patt = 'jkasb'my_dict = {} for pat in patt:my_dict [i] = 1如果我不在my_dict中my_dict [i] +1#检查我是否存在于dict中   < li> 

    使用 dict.get()而没有默认返回值:

      patt ='jkasb'my_dict = {} for我在patt:my_dict [i] = 1如果my_dict.get(i)是None,则my_dict [i] +1#using dict.get print(my_dict)   
  • 使用带有默认返回值的 dict.get()

+50
collections.defaultdict
  from collections import defaultdict d = defaultdict(int)for i in'jkasb':d [i] + = 1   

使用 collections.Counter
  from collections import Counter d = Counter('jkasb')  

避免使用 dict (内置类型)作为变量名。只需迭代'jkasb'而不必将其转换为列表,字符串也是可迭代的。 来自集合导入defaultdict d = defaultdict(int)for i in'jkasb':d [i] + = 1

使用 collections.Counter
  from collections import counter d = Counter('jkasb')  

避免使用 dict (内置类型)作为变量名。只需迭代'jkasb'而不必将其转换为列表,字符串也是可迭代的。 来自集合导入defaultdict d = defaultdict(int)for i in'jkasb':d [i] + = 1

使用 collections.Counter
  from collections import counter d = Counter('jkasb')  

避免使用 dict (内置类型)作为变量名。只需迭代'jkasb'而不必将其转换为列表,字符串也是可迭代的。

+30

由于 dict 最初为空,尝试使用 dict [i] 访问任何值将抛出 KeyError

您应该将其替换为 .get()< / code> 如果未找到密钥则返回 None

  for i in patt:dict [i] = 1 if dict.get( i)是否其他dict [i] + 1   

另一种选择,正如@snakecharmerb所建议的那样,是事先检查你的字典中是否存在密钥: < pre> for pat in patt:dict [i] = 1如果我没有在dict中另外dict [i] + 1

两种解决方案都是等价的,但第二种解决方案可能更“惯用”。

或者也许如果我在dict? - snakecharmerb 2天前

或者简单地说dict [i] = dict.get(i,0)+ 1 - Tomerikoo 2天前

得到它了。Dint知道他们让dict []和dict.get有不同的行为。 - Sachin Verma 2天前

@Tomerikoo谢谢! - Delgan 2天前

0

这些片段: dict [i] dict [i] +1 将尝试从字典中获取一个带有相应键 i的值由于词典中没有任何内容,因此会出现KeyError。

0

您正在尝试访问空字典中的密钥,您也可以使用 defaultdic 所以你不在乎密钥是否已经存在:

  from collections import defaultdict patt = list('jkasb')my_dict = defaultdict(int)for i in patt: my_dict [i] + = 1  
     
			
        
18
votes
answers
32 views
+10

检查集中的任何值

假设我有以下设置:

  things = {'foo','bar','baz'}   

我想要找出该集合中是否存在 bar 我试过了:

 &gt;&gt;&gt; 事物中的“foo”或事物中的“bar”True   

这有效,但如果没有多个语句,是否有更多Pythonic方式进行此检查?我在标准的Python集合操作中找不到任何可以实现此目的的东西。使用 {'foo','bar'}&lt; = things 检查两者,但我想检查其中任何一个。

沙发
+60
+50

只要您使用套装,就可以使用:

  if {'foo','bar'}&amp; 事情:...   

&amp; 表示设置指示,只要它是非空的,交集将是真实的。

+50

说话集,你真正想知道的是交叉点是非空的:

  if thing&amp; {'foo','bar'}:#其中至少有一个在  

并且总是有任何():

  any(t在''foo','bar']中的事物中  

如果您有很长的要检查的事项列表,这是很好的。但是对于两件事,我更喜欢简单的

+30

你正在寻找集合的交集:

  things = {'foo','bar','baz'} things.intersection({'foo','other' })#{'foo'} things.intersection('none','here')#set   

因此,由于空集在布尔上下文中是假的,你可以这样做:

  if things.intersection({'foo','other'}):print(“some common value”)else:print('no one here') 
     
			
        
+20
  things = {'foo','bar','baz'} any([i in in in in ['foo','bar']]) 
     
			
        
+20

您可以使用 set.isdisjoint

  if if things.isdisjoint({'foo','bar'}):...   

set.intersection

  if things.intersection({'foo','bar'}):...   

any

 如果有的话(['foo','bar']中的东西):...   

或者坚持使用,因为这经常是实际上是最易读的解决方案:

 如果事物中的'foo'或事物中的'bar':...  
     
			
        
12
votes
answers
28 views
+10

Pandas转换列表的不一致行为

] = df.groupby(['label'])[['wave']]。transform(list)label wave y new 0 a 1 0 1 1 b 2 0 2 2 b 3 0 3 3 c 4 0 4

有一种解决方法可以获得预期的结果:

  df ['new'] = df.groupby(['label'])[['wave' ]] .transform(tuple)['wave']。apply(list)label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]   

我考虑过可变性/不变性(list / tuple)但是对于set / frozenset它是一致的。

问题是为什么它以这种方式工作? transform(list)label wave y new 0 a 1 0 1 1 b 2 0 2 2 b 3 0 3 3 c 4 0 4

有一种解决方法可以获得预期的结果:

  df ['new'] = df.groupby(['label'])[['wave']]。transform(tuple)['wave'] .applied(list)label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]   

我想到了可变性/不变性(list / tuple)但是对于set / frozenset它是一致的。

问题是为什么它以这种方式工作? transform(list)label wave y new 0 a 1 0 1 1 b 2 0 2 2 b 3 0 3 3 c 4 0 4

有一种解决方法可以获得预期的结果:

  df ['new'] = df.groupby(['label'])[['wave']]。transform(tuple)['wave'] .applied(list)label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]   

我想到了可变性/不变性(list / tuple)但是对于set / frozenset它是一致的。

问题是为什么它以这种方式工作? df ['new'] = df.groupby(['label'])[['wave']]。transform(tuple)['wave']。apply(list)label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]

我想到了可变性/不变性(list / tuple)但是对于set / frozenset它是一致的。

问题是为什么它以这种方式工作? df ['new'] = df.groupby(['label'])[['wave']]。transform(tuple)['wave']。apply(list)label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]

我想到了可变性/不变性(list / tuple)但是对于set / frozenset它是一致的。

问题是为什么它以这种方式工作? 问题是为什么它以这种方式运作? 问题是为什么它以这种方式运作?

沙发
+60

之前我遇到过类似的问题。我认为根本问题是当列表中的元素数量与组中的记录数匹配时,它会尝试解压缩列表,以便列表中的每个元素都映射到组中的记录。

例如,这将导致列表解包,因为列表的len与每个组的长度匹配:

  df.groupby(['label'])[['wave'] ] .transform(lambda x:list(x))wave 0 1 1 2 2 3 3 4   

但是,如果列表的长度与每个组的长度不同,您将得到理想的行为:

  df.groupby(['label'])[['wave']]。transform(lambda x:list(x)+ [0])wave 0 [1 ,0] 1 [2,3,0] 2 [2,3,0] 3 [4,0]  < / pre> 

我认为这是列表解包功能的副作用。

很好的观察!看起来这是一个内部代表中间结果的问题。但我认为这应该仍然是一个错误。 - jottbe 2天前

对我来说,这种行为令人困惑。如果没有简单的补救措施,那么应该删除对转换中列表的支持,或者至少应该添加一些警告。 - Quant Christo 2天前

@QuantChristo,我同意这是一个非常令人困惑的行为,我遇到的类似问题花了我一段时间来弄清楚原因。也许你可以把它归档为bug。 - 艾伦2天前

我创建了一个问题github.com/pandas-dev/pandas/issues/28246 - Quant Christo 2天前

@Shinjo与熊猫相关,类型(df [['wave']])是DataFrame,type(df ['wave'])是Series。 - 昨天的Quant Christo

板凳
+30

我认为这是熊猫的一个错误。你能在他们的github 页面上打开一张票吗?

起初我想,它可能是,因为 list 没有正确地作为 .transform 的参数,但如果我这样做:

  def create_list(obj):print(type(obj))return obj.to_list()df.groupby(['label'])[['wave']]。transform(create_list)  

我得到了同样意想不到的结果。但是如果使用了 agg 方法,它可以直接使用:

  df.groupby(['label'])['wave']。agg(list)Out [179]:标签a [1] b [2,3] c [4]名称:wave,dtype:object   

我无法想象这是预期的行为。

顺便说一下。我还发现了可疑的不同行为,如果您将元组应用于分组系列和分组数据帧,则会显示该行为。例如,如果将 transform 应用于系列而不是DataFrame,结果也不是包含列表的系列,而是包含 ints 的系列(请记住 [[ 'wave']] 创建一个单一的数据帧 transform(tuple)确实返回了元组):

  df.groupby(['label' ])['wave'] .transform(tuple)Out [177]:0 1 1 2 2 3 3 4名称:wave,dtype:int64   

我创建了一个问题github.com/pandas-dev/pandas/issues/28246关于['wave'] vs [['wave']]的事情是你的发现,这是一个单独的问题,所以如果更好的话你只在github上为此创建问题。非常感谢! - Quant Christo 2天前

你不能把它添加到你的票吗?我将不得不经历整个过程来为此设置一个测试用例。 - jottbe 2天前

我已经更新了github问题。感谢帮助。 - 昨天的Quant Christo

大!非常感谢你! - 昨天jottbe

地板
+30

由于 DataFrames 主要用于处理2D数据,因此包括数组而不是标量值可能会偶然发现这一点。

pd.DataFrame。 trasnform 最初是在 .agg 之上实现的:

  #pandas / core / generic.py @Appender(_shared_docs [“transform”]%dict (axis =“”,** _ shared_doc_kwargs))def transform(self,func,* args,** kwargs):result = self.agg(func,* args,** kwargs)if is_scalar(result)or len(result )!= len(self):引发ValueError(“转换不能生成”“聚合结果”)返回结果  

然而,转换总是返回一个必须与self具有相同长度的DataFrame,这本质上就是输入。

当您在 DataFrame 上执行 .agg 函数时,它工作正常:

  df.groupby('label')['wave']。agg(list)label a [1] b [2,3] c [4]名称: wave,dtype:object   

transform 尝试返回长度相同的 Series 时,会引入问题。

在转换 groupby 元素的过程中,该元素是来自 self 的切片,然后再次连接,将列表解压缩到与@Allen提到的索引长度相同的值。

然而,当他们不在t align,然后不要解压缩:

  df.groupby(['label'])[['wave']]。transform(lambda x:list(x)+ [1 ])wave 0 [1,1] 1 [2,3,1] 2 [2,3,1] 3 [4,1]   

解决这个问题的方法可能是避免< code> transform

  df = pd.DataFrame(data = {'label':['a','b','b','c'],' wave':[1,2,3,4],'y':[0,0,0,0]})df = df.merge(df.groupby('label')['wave']。agg( list).rename('new'),on ='label')df label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]  pre>  df.groupby(['label'])[['wave']]。transform(lambda x:list(x)+ [1])wave 0 [1,1] 1 [2,3], 1] 2 [2,3,1] 3 [4,1]   

解决此问题的方法可能是避免 transform

  df = pd.DataFrame(data = {'label':['a','b','b','c'],'wave':[1,2,3,4],'y ':[0,0,0,0]})df = df.merge(df.groupby('label')['wave']。agg(list).rename('new'),on ='label' )df标签wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]  pre>  df.groupby(['label'])[['wave']]。transform(lambda x:list(x)+ [1])wave 0 [1,1] 1 [2,3], 1] 2 [2,3,1] 3 [4,1]   

解决此问题的方法可能是避免 transform

  df = pd.DataFrame(data = {'label':['a','b','b','c'],'wave':[1,2,3,4],'y ':[0,0,0,0]})df = df.merge(df.groupby('label')['wave']。agg(list).rename('new'),on ='label' )df标签wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]  list(x)+ [1])wave 0 [1,1] 1 [2,3,1] 2 [2,3,1] 3 [4,1]   

A解决此问题可能是避免转换

  df = pd.DataFrame(data = {'label':['a','b','b' ,'c'],'wave':[1,2,3,4],'y':[0,0,0,0]})df = df.merge(df.groupby('label')[ 'wave']。agg(list).rename('new'),on ='label')df label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2 ,3] 3 c 4 0 [4]  list(x)+ [1])wave 0 [1,1] 1 [2,3,1] 2 [2,3,1] 3 [4,1]   

A解决此问题可能是避免转换

  df = pd.DataFrame(data = {'label':['a','b','b' ,'c'],'wave':[1,2,3,4],'y':[0,0,0,0]})df = df.merge(df.groupby('label')[ 'wave']。agg(list).rename('new'),on ='label')df label wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2 ,3] 3 c 4 0 [4]  code> df = pd.DataFrame(data = {'label':['a','b','b','c'],'wave':[1,2,3,4],'y' :[0,0,0,0]})df = df.merge(df.groupby('label')['wave']。agg(list).rename('new'),on ='label') df标签wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]  code> df = pd.DataFrame(data = {'label':['a','b','b','c'],'wave':[1,2,3,4],'y' :[0,0,0,0]})df = df.merge(df.groupby('label')['wave']。agg(list).rename('new'),on ='label') df标签wave y new 0 a 1 0 [1] 1 b 2 0 [2,3] 2 b 3 0 [2,3] 3 c 4 0 [4]  3] 3 c 4 0 [4]  3] 3 c 4 0 [4]  
     
			
        

是的,我知道这个解决方法,直到这个问题我认为:transform = groupby。apply + merge,只是一个同步糖 - 2天前的Quant Christo

39
votes
answers
30 views
+10

按连续索引编号分组

我想知道是否有一种方法可以将连续索引编号分组并将组移动到不同的列中。以下是我正在使用的DataFrame示例:

  0 0 19218.965703 1 19247.621650 2 19232.651322 9 19279.216956 10 19330.087371 11 19304.316973   

我的想法是通过顺序索引号得到gruoup并得到这样的结果:

  0 1 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973   

我一直试图分裂我的块数据为3,然后是groupby,但我看起来更多的是可用于分组和重新排列顺序索引号的东西。谢谢!

up vote 16 down vote accepted favorite
沙发
+160
+50

以下是一种方法:来自more_itertools的

 导入continuous_groups final = pd.concat([df.loc [i] .reset_index(drop = True)for i in consecutive_groups(df.index) )],axis = 1)final.columns = range(len(final.columns))print(final)  
  0 1 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973  
     
			
        
+70

这是 groupby + pivot_table


  m = df.index.to_series()。diff()。 ne(1).cumsum()(df.assign(key = df.groupby(m).cumcount())。pivot_table(index ='key',columns = m,values = 0))  

  1 2 key 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973  
     
			
        
+70

使用新的 pandas.MultiIndex
  a = pd.factorize(df.index  -  np)创建新的 pandas.Series  .arange(len(df)))[0] b = df.groupby(a).cumcount()pd.Series(df ['0']。to_numpy(),[b,a])。unstack()0 1 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973   

类似但有更多Numpy
  a = pd.factorize(df.index  -  np .arange(len(df)))[0] b = df.groupby(a).cumcount()c = np.empty((b.max()+ 1,a.max()+ 1),float) c.fill(np.nan)c [b,a] = np.ravel(df)pd.DataFrame(c)0 1 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973  
     
			
        

+60

pandas groupby

  s = df.index.to_series()。diff()。ne(1) .cumsum()pd.concat({x:y.reset_index(drop = True)表示x,y表示df ['0']。groupby(s)},axis = 1)Out [786]:1 2 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973  
     
			
        
+20

我认为你假设每个连续组内的观察数量是相同的。我的方法是:

准备数据:

 将pandas导入pd import numpy as np df = pd.DataFrame(data = {'data':[19218.965703,19247.621650] ,19232.651322,19279.216956,19330.087371,19304.316973]},index = [0,1,2,9,10,11])  

解决方案:

 < code> df ['Group'] =(df.index.to_series() -  np.arange(df.shape [0]))。rank(method ='dense')df.reset_index(inplace = True)df [' Observations'] = df.groupby(['Group'])['index']。rank()df.pivot(index ='Observations',columns ='Group',values ='data') < / pre> 

返回:

     
			
        
+10

我的方式:

  df ['groups'] = list(df.reset_index()['index']  -  range(0,len(df)))pd.concat( [df ['groups'] == i] [['0']]。reset_index(drop = True)for d in df ['groups']。unique()],axis = 1)0 0 0 19218.965703 19279.216956 1 19247.621650 19330.087371 2 19232.651322 19304.316973  
     
			
        
0
votes
answers
51 views
+10

的Python大青葉等值線繪製

2

我試圖用我從這裏下載GeoJSON的數據文件繪製英國的等值線圖:https://data.gov.uk/dataset/regions-december-2016-full-extent-boundaries-in-england2的Python大青葉等值線繪製

下面是JSON數據的例子:

{ 
    "type":"FeatureCollection", 
    "features":[ 
    { 
     "type":"Feature", 
     "properties":{"objectid":1,"rgn16cd":"E12000001","rgn16nm":"North East","bng_e":417313,"bng_n":600358,"long":-1.72889996,"lat":55.2970314,"st_areashape":8675727008.425964,"st_lengthshape":795456.8022925043}, 
     "geometry":{ 
     "type":"MultiPolygon", 
     "coordinates":[[[[-2.03,55.80991509288915],[-2.030069429494278,55.80991420787532],[-2.0300215494803053,55.80992140589199],[-2.0300040593387223,55.80993039246682], 

我csv文件看起來像這樣: csv

我基本上只是想使用葉子繪製Taxi列。

問題是情節不顯示任何東西。我使用了下面的代碼。

import pandas as pd 
import os 
import json 

# read in population data 
df = pd.read_csv('map-data.csv') 

import folium 
from branca.utilities import split_six 
state_geo = 'Regions_December_2016_Full_Extent_Boundaries_in_England.geojson' 

m = folium.Map(location=[55, 4], zoom_start=5) 
m.choropleth(
    geo_data=state_geo, 
    data=df, 
    columns=['LA-Code', 'Taxi'], 
    key_on='feature.properties.rgn16cd', 
    fill_color='YlGn', 
    fill_opacity=0.7, 
    line_opacity=0.2, 
    legend_name='h', 
    highlight=True 
) 

m 

我認爲這個問題與key_on參數有關。 我可以在JSON文件使用像這樣訪問正確的代碼:

geodata['features'][0]['properties']['rgn16cd'] 

這使我回到了正確的LA碼(E12000001),但它似乎 沒有在上面的代碼工作。我使用的KEY_ON參數的功能,而不是功能也試過,但那個給我一個錯誤

AttributeError的:「NoneType」對象有沒有屬性「得到」

沒有人有任何想法的問題是什麼?謝謝。

沙发
0
1

folium library's documentation on github

To display it in a Jupyter notebook, simply ask for the object representation:

In : m

很可能是你的問題的根源是,你是不是在木星的筆記本。將地圖保存爲html文件並在瀏覽器中打開它可以正常工作,無需更改json文件。試試下面的代碼:

import pandas as pd 
import folium 

# read in population data 
df = pd.read_csv('map-data.csv') 
state_geo = 'Regions_December_2016.geojson' 


m = folium.Map(location=[55, 4], zoom_start=5) 
m.choropleth(
    geo_data=state_geo, 
    data=df, 
    columns=['LA-Code', 'Taxi'], 
    key_on='feature.properties.rgn16cd', 
    fill_color='YlGn', 
    fill_opacity=0.7, 
    line_opacity=0.2, 
    legend_name='h', 
    highlight=True 
) 

m.save("my_map.html") 

要打開腳本中的地圖,可以通過subprocess.callos.system打電話給你的網絡瀏覽器,通過將這些線在腳本的末尾:

import os 
os.system("firefox my_map.html")