【问题标题】:Check existence of column names检查列名是否存在
【发布时间】:2014-10-27 23:38:53
【问题描述】:

我有一个数据框 df,其中包含一系列年份的许多字段名称。

                                                   field
year description                                               
1993 bar0                                       a01arb92
     bar1                                       a01svb92
     bar2                                       a01fam92
     bar3                                       a08
     bar4                                       a01bea93

然后,对于每一年,我都有一个 stata 文件,其中包含 id 作为列和附加列,df 中提到的部分(或全部)字段名称。例如,1993.dta 可以是

id a01arb92 a01svb92 a08 a01bea93
0         1        1   1        1
0         1        1   1        2

我需要每年检查df 中列出的所有字段是否确实存在于相应文件中(作为列)。然后我想将结果保存回原始数据框中。有没有一种不用遍历每个字段的好方法?

预期输出:

                                                   field   exists
year description                                               
1993 bar0                                       a01arb92        1
     bar1                                       a01svb92        1
     bar2                                       a01fam92        0
     bar3                                       a08             1
     bar4                                       a01bea93        1

例如,如果除a01fam92 之外的每个字段都作为列存在于 1993 文件中。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这是一种利用 pandas 会自动为缺失索引填充 NaN 的方法。

    首先准备数据。您可能已经完成了这一步。

    df1 = pd.read_csv(r'c:\temp\test1.txt', sep=' ')
    
    df1
    Out[30]: 
       year description     field
    0  1993        bar0  a01arb92
    1  1993        bar1  a01svb92
    2  1993        bar2  a01fam92
    3  1993        bar3       a08
    4  1993        bar4  a01bea93
    
    df1 = df1.set_index(['year', 'description', 'field'])
    
    df2 = pd.read_csv(r'c:\temp\test2.txt', sep=' ')
    
    df2
    Out[33]: 
       year description     field
    0  1993        bar0  a01arb92
    1  1993        bar1  a01svb92
    2  1993        bar3       a08
    3  1993        bar4  a01bea93
    
    df2 = df2.set_index(['year', 'description', 'field'])
    

    接下来,在 df2 中创建一个新列,并使用 pandas 将该列复制到上一个数据帧中。这将为缺失值填充 NaN。然后使用fillna 赋值为0。

    df2['exists'] = 1
    
    df1['exists'] = df2['exists']
    
    df1
    Out[37]: 
                               exists
    year description field           
    1993 bar0        a01arb92       1
         bar1        a01svb92       1
         bar2        a01fam92     NaN
         bar3        a08            1
         bar4        a01bea93       1
    
    df1.fillna(0)
    Out[38]: 
                               exists
    year description field           
    1993 bar0        a01arb92       1
         bar1        a01svb92       1
         bar2        a01fam92       0
         bar3        a08            1
         bar4        a01bea93       1
    

    【讨论】:

    • 感谢您的回答。看来我的问题表述得很糟糕:df2df1 的结构不同,它在df1 中列出了fields 作为列。我更新了问题,希望对您有所帮助。
    【解决方案2】:

    尝试每年进行一次,过滤数据框以获取与每个特定年份关联的字段,然后比较元素是否在 stata 文件中。

     import pandas as pd
     d= pd.stata.read_stata("file")
    
    • 读取您的 csv 文件,并将其存储在数据框中
     import pandas as pd
     df= pd.read_csv("file")
    
    • 过滤并提取每年的字段。
    df[df["year"]==1993].fields #Output: List of fields in year 1993
    

    您可以通过查看年份列表来概括该过程

    l= df.year
    for x in l:
       f= df[df["year"]==x].fields
       # Then check if f in strata file.
    

    这里有详细的说明如何filter fields using Pandas

    • 将 starata 字段与您拥有的列表进行比较

    您可以使用All() 运算符。

    All(item for item in f if item in d)
    

    如果为 True,则该字段中的所有元素都在地层文件中。

    把所有东西都放在一个函数中。

    l= df.year #List of years
    IsInDic={} #Dictinary to store a year:<All Fields in stata field> eg: {1993:True}
    for x in l:
        f= df[df["year"]==x].fields
       # Then check if f in strata file.
        isInList= All(item for item in f if item in d)
        IsInDic[x]=isInList #Add everything in a dictionary to help you later decide whether it's true or no.
    

    更新

    def isInList(x):
      return  [ x for x in d if x in df[df["year"]==x].fields] == d
    

    【讨论】:

    • 嗯,这就是我最初的想法。但这是对每个文件的迭代,然后,在将其保存在字典中之后,我想我必须将其迭代到原始数据帧上。有没有办法利用dfd都是数据框的事实?
    • @FooBar 检查更新。如果我们可以使用过滤呢?我们创建一个过滤列表,如果它在字段中,我们将附加到 d 中的每个元素,然后将结果与 d 进行比较。如果我们得到相同的列表,则意味着所有元素都在字段中,反之则为 false。
    • 我认为你的更新应该是return [...] == df[df["year"]==x].fields。但是,我只知道它是否包含 all 的字段。为了恢复问题中的预期输出,我仍然需要遍历所有字段,不是吗?
    • 真的!您应该通过必须选择与每年相关的字段的年份集(这将帮助您更早地发现问题)。
    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 2018-09-21
    • 2014-04-27
    • 2021-01-31
    • 2010-10-02
    • 1970-01-01
    • 2013-05-04
    • 2015-08-03
    相关资源
    最近更新 更多