ここにあるように、国勢調査局のAmerican Community Survey Public Use Microsampleデータリリースのデータディクショナリを読み取って解析しようとしています。
いくつかの説明ノートが挿入されているところにいくつかの抜けがありますが、かなりよく構成されています。
私の好ましい結果は、変数ごとに1行のデータフレームを取得し、特定の変数のすべての値ラベルを同じ行の値ディクショナリフィールドに格納された1つのディクショナリにシリアル化することだと思います(ただし、階層的なjsonのような形式はそうではありません悪いですが、より複雑です。
次のコードを取得しました。
import pandas as pd
import re
import urllib2
data = urllib2.urlopen('http://www.census.gov/acs/www/Downloads/data_documentation/pums/DataDict/PUMSDataDict13.txt')
## replace newline characters so we can use dots and find everything until a double
## carriage return (replaced to ||) with a lookahead assertion.
data=data.replace('\n','|')
datadict=pd.DataFrame(re.findall("([A-Z]{2,8})\s{2,9}([0-9]{1})\s{2,6}\|\s{2,4}([A-Za-z\-\(\) ]{3,85})",data,re.MULTILINE),columns=['variable','width','description'])
datadict.head(5)
+----+----------+-------+------------------------------------------------+
| | variable | width | description |
+----+----------+-------+------------------------------------------------+
| 0 | RT | 1 | Record Type |
+----+----------+-------+------------------------------------------------+
| 1 | SERIALNO | 7 | Housing unit |
+----+----------+-------+------------------------------------------------+
| 2 | DIVISION | 1 | Division code |
+----+----------+-------+------------------------------------------------+
| 3 | PUMA | 5 | Public use microdata area code (PUMA) based on |
+----+----------+-------+------------------------------------------------+
| 4 | REGION | 1 | Region code |
+----+----------+-------+------------------------------------------------+
| 5 | ST | 2 | State Code |
+----+----------+-------+------------------------------------------------+
ここまでは順調ですね。変数のリストと、それぞれの文字数の幅があります。
これを展開して、追加の行 (値ラベルが存在する場所) を取得できます。次のようにします。
datadict_exp=pd.DataFrame(
re.findall("([A-Z]{2,9})\s{2,9}([0-9]{1})\s{2,6}\|\s{4}([A-Za-z\-\(\)\;\<\> 0-9]{2,85})\|\s{11,15}([a-z0-9]{0,2})[ ]\.([A-Za-z/\-\(\) ]{2,120})",
data,re.MULTILINE))
datadict_exp.head(5)
+----+----------+-------+---------------------------------------------------+---------+--------------+
| id | variable | width | description | value_1 | label_1 |
+----+----------+-------+---------------------------------------------------+---------+--------------+
| 0 | DIVISION | 1 | Division code | 0 | Puerto Rico |
+----+----------+-------+---------------------------------------------------+---------+--------------+
| 1 | REGION | 1 | Region code | 1 | Northeast |
+----+----------+-------+---------------------------------------------------+---------+--------------+
| 2 | ST | 2 | State Code | 1 | Alabama/AL |
+----+----------+-------+---------------------------------------------------+---------+--------------+
| 3 | NP | 2 | Number of person records following this housin... | 0 | Vacant unit |
+----+----------+-------+---------------------------------------------------+---------+--------------+
| 4 | TYPE | 1 | Type of unit | 1 | Housing unit |
+----+----------+-------+---------------------------------------------------+---------+--------------+
したがって、最初の値と関連するラベルが取得されます。私の正規表現の問題は、最初から最後まで複数行の一致を繰り返す方法です。\s{11,15}
つまり、いくつかの変数には大量の一意の値があります(ST
またはstate code
、各状態の値とラベルを示す約50行が続きます)。
ソース ファイルのキャリッジ リターンの早い段階でパイプを使用して変更しました。その特定の変数の終わりを示すダブル キャリッジ リターンまで、恥知らずにすべてを一致させるためにドットに頼ることができると考えていましたが、ここで行き詰まりました。
では、複数行のパターンを任意の回数繰り返す方法。
(後で複雑になるのは、一部の変数が辞書に完全に列挙されていないことですが、値の有効な範囲で示されています。NP
たとえば、[同じ世帯に関連付けられている人の数] は、次のように「02..20」で示されます)。これを考慮しないと、もちろん、私の解析ではそのようなエントリが見落とされます。)