[英]Parsing structured but non-tabular text into pandas using regular expressions
[英]Pandas: parsing values in structured non tabular text
我有一個文本文件,格式如下:
k1[a-token]
v1
v2
k2[a-token]
v1'
k3[a-token]
v1"
v2"
v3"
將這些數據讀入此表單的數據框中最令人饒恕的方式是什么:
A B
0 k1 v1
1 k1 v2
2 k2 v1'
3 k3 v1"
4 k3 v2"
5 k3 v3"
那不涉及手動循環? 或者是否有任何其他庫允許我只輸入一些正則表達式,這些表達式將指定我的文本文件的結構並以上述表格形式輸出數據?
建立
借用@jezrael
import pandas as pd
from pandas.compat import StringIO
temp=u"""
k1[a-token]
v1
v2
k2[a-token]
v1'
k3[a-token]
v1"
v2"
v3"
"""
#after testing replace 'StringIO(temp)' to 'filename.csv'
df = pd.read_csv(StringIO(temp), sep="|", names=['B'])
print (df)
str.extract
使用正則表達式中指定的參數並向前看 duplicated
來標識我們想要保留的行。 df = df.B.str.extract('(?P<A>.*(?=\[a-token\]))?(?P<B>.*)', expand=True).ffill()
df[df.duplicated(subset=['A'])].reset_index(drop=True)
A B
0 k1 v1
1 k1 v2
2 k2 v1'
3 k3 v1"
4 k3 v2"
5 k3 v3"
您可以將read_csv
與某些分隔符一起使用,該分隔符不在像|
那樣的數據中 或¥
:
import pandas as pd
from pandas.compat import StringIO
temp=u"""
k1[a-token]
v1
v2
k2[a-token]
v1'
k3[a-token]
v1"
v2"
v3"
"""
#after testing replace 'StringIO(temp)' to 'filename.csv'
df = pd.read_csv(StringIO(temp), sep="|", names=['B'])
print (df)
B
0 k1[a-token]
1 v1
2 v2
3 k2[a-token]
4 v1'
5 k3[a-token]
6 v1"
7 v2"
8 v3"
然后使用[a-token]
insert
帶有extract
值的新列A
,最后使用帶duplicated
掩碼的boolean indexing
,以刪除values
列中帶keys
行:
df.insert(0, 'A', df['B'].str.extract('(.*)\[a-token\]', expand=False).ffill())
df = df[df['A'].duplicated()].reset_index(drop=True)
print (df)
A B
0 k1 v1
1 k1 v2
2 k2 v1'
3 k3 v1"
4 k3 v2"
5 k3 v3"
但是如果文件有重復的keys
:
print (df)
B
0 k1[a-token]
1 v1
2 v2
3 k2[a-token]
4 v1'
5 k3[a-token]
6 v1"
7 v2"
8 v3"
9 k2[a-token]
10 v1'
df.insert(0, 'A', df['B'].str.extract('(.*)\[a-token\]', expand=False).ffill())
df = df[df['A'].duplicated()].reset_index(drop=True)
print (df)
A B
0 k1 v1
1 k1 v2
2 k2 v1'
3 k3 v1"
4 k3 v2"
5 k3 v3"
6 k2 k2[a-token]
7 k2 v1'
然后是必要的更改mask
:
df.insert(0, 'A', df['B'].str.extract('(.*)\[a-token\]', expand=False).ffill())
df = df[~df['B'].str.contains('\[a-token]')].reset_index(drop=True)
print (df)
A B
0 k1 v1
1 k1 v2
2 k2 v1'
3 k3 v1"
4 k3 v2"
5 k3 v3"
6 k2 v1'
將您的文件設為'temp.txt'...
df = pd.read_csv('temp.txt',
header=None,
delim_whitespace=True,
names=['data'])
bins = df.data.str.endswith('[a-token]')
idx_bins = df[bins][:]
idx_bins.data = idx_bins.data.str.rstrip(to_strip='[a-token]')
idx_vals = df[~bins][:]
a = pd.DataFrame(idx_bins.index.values, columns=['a'])
b = pd.DataFrame(idx_vals.index.values, columns=['b'])
merge_df = pd.merge_asof(b, a, left_on='b', right_on='a')
new_df = pd.DataFrame({'A': idx_bins.data.loc[list(merge_df.a)].values,
'B': idx_vals.data.values})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.