【问题标题】:How do I make new columns in dataframe from a row of a different column?如何从不同列的一行在数据框中创建新列?
【发布时间】:2016-03-11 08:04:01
【问题描述】:

这是我当前的数据框:

>>>df = {'most_exhibitions' : pd.Series(['USA (1) Netherlands (5)' ,
'United Kingdom (2)','China (3) India (5) Pakistan (8)','USA (11) India (4)'], index=['a', 'b', 'c','d']), 
              'name' : pd.Series(['Bob', 'Joe', 'Alex', 'Bill'], index=['a', 'b', 'c','d'])}

>>> df
  name                  most_exhibitions
a Bob                  USA (1) India (5)
b Joe                 United Kingdom (2)
c Alex       China (3) India (5) USA (8)
d Bill                USA (11) India (4)

我正在尝试弄清楚如何拆分每个单元格,然后可能会从国家/地区创建一个新列并将相应的计数放在正确的行中。如果国家/地区已经是现有列,我只想将计数放在正确的行中。

所以,最终的数据框应该是这样的:

#    name                   most_exhibitions            USA    United Kingdom    China    India    
#a   Bob                  USA (1), India (5)              1                                   5
#b   Joe                  United Kingdom (2)                                2
#c   Alex      China (3), India (5), USA (8)              8                          3        5
#d   Bill                USA (11), India (4)             11                                   4

我想编写一个循环或函数来拆分数据,然后添加新列,但我不知道该怎么做。我最终通过一系列字典拆分和清理数据,现在我陷入了如何将最终字典变成自己的数据框的问题。我想,如果我能制作这个新的数据框,我就可以将它附加到旧的数据框上。我也认为我做的比它应该做的更难,并且对任何更优雅的解决方案感兴趣。

这是我到目前为止所做的:

>>>country_rank_df['country_split'] 
= indexed_rankdata['most_exhibitions'].str.split(",").astype(str)

from collections import defaultdict
total_dict = defaultdict(list)

dict2 = defaultdict(list)
dict3 = defaultdict(list)
dict4 = defaultdict(list)
dict5 = defaultdict(list)
dict6 = defaultdict(list)

for name, country_count in zip(head_df['name'], head_df['most_exhibitions']):

    total_dict[name].append(country_count)

for key, value in total_dict.iteritems():
    for line in value:
        new_line = line.split('(')
        dict2[key].append(new_line)

for key, list_outside in dict2.iteritems():
    for list_inside in list_outside:
        for value in list_inside:
            new_line = value.split(',')
            dict3[key].append(new_line)

for key, list_outside in dict3.iteritems():
    for list_inside in list_outside:
        for value in list_inside:
            new_line = value.split(')')
            dict4[key].append(new_line)

for key, list_outside in dict4.iteritems():
    for list_inside in list_outside:
        for value in list_inside:
            new_line = value.strip()
            new_line = value.lstrip()
            dict5[key].append(new_line)

for key, list_outside in dict5.iteritems():
    new_line = filter(None, list_outside)
    dict6[key].append(new_line)

>>>dict6['Bob']

[['USA',
  '1',
  'India',
  '5']]

【问题讨论】:

    标签: python for-loop dictionary pandas


    【解决方案1】:

    您可以尝试这种方法,主要使用string methods。然后我pivotfillna 数据框。我丢失了原始专栏most_exhibitions,但我希望它是不必要的。

    import pandas as pd
    
    df = {'most_exhibitions' : pd.Series(['USA (1) Netherlands (5)' ,
    'United Kingdom (2)','China (3) India (5) Pakistan (8)','USA (11) India (4)'], index=['a', 'b', 'c','d']), 
                  'name' : pd.Series(['Bob', 'Joe', 'Alex', 'Bill'], index=['a', 'b', 'c','d'])}
    
    df = pd.DataFrame(df)
    #cange ordering of columns
    df = df[['name', 'most_exhibitions']]
    print df
    #   name                  most_exhibitions
    #a   Bob           USA (1) Netherlands (5)
    #b   Joe                United Kingdom (2)
    #c  Alex  China (3) India (5) Pakistan (8)
    #d  Bill                USA (11) India (4)
    
    
    #remove '(' and last ')'
    df['most_exhibitions'] = df['most_exhibitions'].str.replace('(', '')
    df['most_exhibitions'] = df['most_exhibitions'].str.strip(')')
    
    #http://stackoverflow.com/a/34065937/2901002
    s = df['most_exhibitions'].str.split(')').apply(pd.Series, 1).stack()
    s.index = s.index.droplevel(-1)
    s.name = 'most_exhibitions'
    print s
    #a               USA 1
    #a       Netherlands 5
    #b    United Kingdom 2
    #c             China 3
    #c             India 5
    #c          Pakistan 8
    #d              USA 11
    #d             India 4
    #Name: most_exhibitions, dtype: object
    
    df = df.drop( ['most_exhibitions'], axis=1)
    df = df.join(s)
    print df
    #   name  most_exhibitions
    #a   Bob             USA 1
    #a   Bob     Netherlands 5
    #b   Joe  United Kingdom 2
    #c  Alex           China 3
    #c  Alex           India 5
    #c  Alex        Pakistan 8
    #d  Bill            USA 11
    #d  Bill           India 4
    
    #exctract numbers and convert them to integer
    df['numbers'] = df['most_exhibitions'].str.extract("(\d+)").astype('int')
    #exctract text of most_exhibitions
    df['most_exhibitions'] = df['most_exhibitions'].str.rsplit(' ', n=1).str[0]
    print df
    #   name most_exhibitions  numbers
    #a   Bob              USA        1
    #a   Bob      Netherlands        5
    #b   Joe   United Kingdom        2
    #c  Alex            China        3
    #c  Alex            India        5
    #c  Alex         Pakistan        8
    #d  Bill              USA       11
    #d  Bill            India        4
    
    #pivot dataframe
    df = df.pivot(index='name', columns='most_exhibitions', values='numbers')
    #NaN to empty string 
    df = df.fillna('')
    
    print df
    #most_exhibitions  India  Netherlands  Pakistan China USA United Kingdom
    #name                                                                   
    #Alex                  5                      8     3                   
    #Bill                  4                               11               
    #Bob                                5                   1               
    #Joe                                                                   2
    

    编辑:

    我尝试将所有列添加为函数merge的推荐输出:

    import pandas as pd
    
    df = {'most_exhibitions' : pd.Series(['USA (1) Netherlands (5)' ,
    'United Kingdom (2)','China (3) India (5) Pakistan (8)','USA (11) India (4)'], index=['a', 'b', 'c','d']), 
                  'name' : pd.Series(['Bob', 'Joe', 'Alex', 'Bill'], index=['a', 'b', 'c','d'])}
    
    df = pd.DataFrame(df)
    #cange ordering of columns
    df = df[['name', 'most_exhibitions']]
    print df
    #   name                  most_exhibitions
    #a   Bob           USA (1) Netherlands (5)
    #b   Joe                United Kingdom (2)
    #c  Alex  China (3) India (5) Pakistan (8)
    #d  Bill                USA (11) India (4)
    
    #copy original to new dataframe for joining original df
    df1 = df.reset_index().copy()
    
    #remove '(' and last ')'
    df['most_exhibitions'] = df['most_exhibitions'].str.replace('(', '')
    df['most_exhibitions'] = df['most_exhibitions'].str.strip(')')
    
    #http://stackoverflow.com/a/34065937/2901002
    s = df['most_exhibitions'].str.split(')').apply(pd.Series, 1).stack()
    s.index = s.index.droplevel(-1)
    s.name = 'most_exhibitions'
    print s
    #a               USA 1
    #a       Netherlands 5
    #b    United Kingdom 2
    #c             China 3
    #c             India 5
    #c          Pakistan 8
    #d              USA 11
    #d             India 4
    #Name: most_exhibitions, dtype: object
    
    df = df.drop( ['most_exhibitions'], axis=1)
    df = df.join(s)
    print df
    #   name  most_exhibitions
    #a   Bob             USA 1
    #a   Bob     Netherlands 5
    #b   Joe  United Kingdom 2
    #c  Alex           China 3
    #c  Alex           India 5
    #c  Alex        Pakistan 8
    #d  Bill            USA 11
    #d  Bill           India 4
    
    #exctract numbers and convert them to integer
    df['numbers'] = df['most_exhibitions'].str.extract("(\d+)").astype('int')
    #exctract text of most_exhibitions
    df['most_exhibitions'] = df['most_exhibitions'].str.rsplit(' ', n=1).str[0]
    print df
    #   name most_exhibitions  numbers
    #a   Bob              USA        1
    #a   Bob      Netherlands        5
    #b   Joe   United Kingdom        2
    #c  Alex            China        3
    #c  Alex            India        5
    #c  Alex         Pakistan        8
    #d  Bill              USA       11
    #d  Bill            India        4
    
    #pivot dataframe
    df = df.pivot(index='name', columns='most_exhibitions', values='numbers')
    #NaN to empty string 
    df = df.fillna('')
    df = df.reset_index()
    
    print df
    #most_exhibitions  name  India  Netherlands  Pakistan China USA United Kingdom
    #0                 Alex      5                      8     3                   
    #1                 Bill      4                               11               
    #2                  Bob                   5                   1               
    #3                  Joe                                                      2
    print df1
    #  index  name                  most_exhibitions
    #0     a   Bob           USA (1) Netherlands (5)
    #1     b   Joe                United Kingdom (2)
    #2     c  Alex  China (3) India (5) Pakistan (8)
    #3     d  Bill                USA (11) India (4)
    df = pd.merge(df1,df, on=['name'])
    df = df.set_index('index')
    
    print df
    #       name                  most_exhibitions  India  Netherlands  Pakistan  \
    #index                                                                         
    #a       Bob           USA (1) Netherlands (5)                   5             
    #b       Joe                United Kingdom (2)                                 
    #c      Alex  China (3) India (5) Pakistan (8)      5                      8   
    #d      Bill                USA (11) India (4)      4                          
    #
    #      China USA United Kingdom  
    #index                           
    #a             1                 
    #b                            2  
    #c         3                     
    #d            11                 
    

    【讨论】:

    • 谢谢@jezrael。当我尝试以下操作时:name_exhibitions_df_2['most_exhibitions'] = name_exhibitions_df_2['most_exhibitions'].str.rsplit(' ', n=1).str[0],我收到此错误:AttributeError: 'StringMethods' object has no attribute 'rsplit'。你知道这是为什么吗?我正在使用 Python 2.7.8 和 iPython 2.1.0。
    • 这个错误与您的样本有关吗?什么版本的熊猫使用print pd.__version__
    • 感谢您如此迅速地提供帮助。是的,它不适用于我的示例.. 0.14.0 版
    • 我认为问题出在版本上。我重新开始通过conda update pandas 更新它。现在的版本是0.17.1
    • 我尝试过,并尝试查看是否有其他人在网上遇到问题,但找不到任何人......当我输入 conda update pandas 时,我得到:SyntaxError: invalid syntax。抱歉问了这么多基本问题。
    猜你喜欢
    • 1970-01-01
    • 2020-11-16
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 2018-03-04
    相关资源
    最近更新 更多