2014-10-27 103 views
0

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

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

然后,对于每一年,我有了iddf提到的字段名称的列和其他列,部分(或全部)一STATA文件。例如,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年文件作为列存在。

回答

0

尽量每年都去,过滤数据框以获取与每个特定年份相关联的字段,然后比较元素是否在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详细解释generlize过程。

  • 比较列表starata领域你有

可以使用All()操作。

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

如果它是真的,那么该字段中的所有元素都在分层文件中。

使一个功能。

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. 

UPDATE

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

那么,这就是我最初的想法。但是,它遍历每个文件,然后在将其保存为字典后,我会假设必须将其迭代到原始数据框上。没有办法使用'df'和'd'都是数据帧的事实吗? – FooBar 2014-10-28 16:55:38

+0

@FooBar检查更新。如果我们可以使用过滤呢我们创建一个过滤列表,在d中添加每个元素(如果它在字段中),然后将结果与d进行比较。如果我们得到相同的列表,则意味着所有元素都在字段中,在相反的情况下是错误的。 – 2014-10-29 13:30:51

+0

我认为你的更新应该读取'return [...] == df [df [“year”] == x] .fields'。但是,我只知道它是否包含*全部*的字段。为了恢复问题中的预期输出,我仍然需要遍历所有的字段,不是吗? – FooBar 2014-10-29 14:48:57

0

这里是一个办法做到这一点利用的事实,熊猫会自动填入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和使用熊猫新的列到列复制到以前的数据帧。这将填补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 
+0

感谢您的回答。看起来我的问题很不明确:'df2'与'df1'没有相同的结构,它有'df1'中列出的'fields'作为列。我更新了这个问题,我希望有所帮助。 – FooBar 2014-10-29 14:43:42