[英]python xml and csv extract
我有 2 组文件 - (1) CSV 文件(主文件)(2)XML 文件。
CSV 文件 -
emp_id
1
2
3
4
XML 文件 -
<employee>
<emp id="1" />
<emp id="2" active="yes">
<tag k="age" v="55" />
</emp>
<emp id="3" active="yes">
<tag k="name" v="scott" />
</emp>
<emp id="4" active="no">
<tag k="address" v="Texas" />
</emp>
<emp id="5" gender="male"/>
<emp id="8" />
<emp id="9" />
<emp id="10" />
<emp id="11" />
</employee>
我的目标是有一个 csv 文件,其中 csv 文件中的 emp_id 与 XML 文件匹配,并且在新的 csv 文件中只创建匹配的 emp_id。 我需要 2 个 csv 文件,如下所示 -
第一个文件。
emp_id,active,gender
1,,
2,yes,
3,yes,
4,no,
5,,male
第二个文件。
emp_id,key,value
2,age,55
3,name,scott
4,address,Texas
我可以在 Pandas 中读取 CSV 文件,在 Python 中读取 XML 文件。 但不知道如何组合它们并从 XML 中提取键和值
任何帮助表示赞赏。
另一种方法。
from simplified_scrapy import SimplifiedDoc, utils
empIds = ['1', '2', '3', '4', '5']
# empIds = [id.strip() for id in utils.getFileLines('your csv file path')[1:]]
xml = '''<employee>
<emp id="1" />
<emp id="2" active="yes">
<tag k="age" v="55" />
</emp>
<emp id="3" active="yes">
<tag k="name" v="scott" />
</emp>
<emp id="4" active="no">
<tag k="address" v="Texas" />
</emp>
<emp id="5" gender="male"/>
<emp id="8" />
<emp id="9" />
<emp id="10" />
<emp id="11" />
</employee>
'''
# xml = utils.getFileContent('your xml file path')
rows1 = [['emp_id', 'active', 'gender']]
rows2 = [['emp_id', 'key', 'value']]
doc = SimplifiedDoc(xml)
for id in empIds:
emp = doc.select('emp#' + id)
if emp:
rows1.append([id, emp.get('active'), emp.get('gender')])
tags = emp.selects('tag')
if tags:
for tag in tags:
rows2.append([id, tag['k'], tag['v']])
utils.save2csv('csv1.csv', rows1, newline='')
utils.save2csv('csv2.csv', rows2, newline='')
结果 csv1:
emp_id,active,gender
1,,
2,yes,
3,yes,
4,no,
5,,male
结果 csv2:
emp_id,key,value
2,age,55
3,name,scott
4,address,Texas
首先df:读取XML并创建DataFrame
import xmltodict
with open('XmlFile.xml') as fd:
xmlfile = xmltodict.parse(fd.read())
df_xmlfile = pd.DataFrame(xmlfile["employee"]["emp"])
df_xmlfile.columns = [col.replace("@","") for col in df_xmlfile.columns]
将 CSV 读取为 DataFrame
df_csvfile = csvfile=pd.read_csv("CsvFile.txt")
加入两个 dfs
df_first = df_csvfile.join(df_xmlfile[["active", "gender"]])
第二个 df:获取包含标签的行,解压这些行以获取键和值并创建第二个 df
df_temp = df_xmlfile[~df_xmlfile["tag"].isna()][["id", "tag"]]
df_second = pd.DataFrame({"emp_id": df_temp["id"],
"key": [row["@k"] for row in df_temp["tag"]],
"value": [row["@v"] for row in df_temp["tag"]]})
让我们创建第一个数据框:
# this dataframe should be read from csv in your case
df = pd.DataFrame({
'emp_id':[1, 2, 3, 4, 5]
})
比定义 XML:
xml = '''<employee>
<emp id="1" />
<emp id="2" active="yes">
<tag k="age" v="55" />
</emp>
<emp id="3" active="yes">
<tag k="name" v="scott" />
</emp>
<emp id="4" active="no">
<tag k="address" v="Texas" />
</emp>
<emp id="5" gender="male"/>
<emp id="8" />
<emp id="9" />
<emp id="10" />
<emp id="11" />
</employee>'''
从 XML 读取数据:
d = defaultdict(list)
# here we read XML from string, in your case it should be read from file
root = et.fromstring(xml)
emps = root.xpath('//employee/emp')
# iterate over elements "emp" and extract data
for emp in emps:
# here we extract attributes id, active and gender
d['id'].append(int(emp.get('id')))
d['active'].append(None if emp.get('active') is None else emp.get('active'))
d['gender'].append(None if emp.get('gender') is None else emp.get('gender'))
# here we extract age
age = emp.find('./tag[@k="age"]')
d['age'].append(None if age is None else age.get('v'))
# here we extract address
address = emp.find('./tag[@k="address"]')
d['address'].append(None if address is None else address.get('v'))
比从 dict 创建数据帧:
df_xml = pd.DataFrame(d)
比使用 emp_id / id 列合并数据:
df_merged = pd.merge(df, df_xml, left_on = 'emp_id', right_on='id', how = 'inner')
del df_merged['id']
df_merged.head(10)
输出:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.