我有一些数据正在从 XML 解析为 Pandas DataFrame。XML 数据大致如下所示:
<tracks>
<track name="trackname1" variants="1,2,3,4,5">
<variant var="1,2,3">
<leg time="21:23" route_id="5" stop_id="103" serial="1"/>
<leg time="21:26" route_id="5" stop_id="17" serial="2"/>
<leg time="21:30" route_id="5" stop_id="38" serial="3"/>
<leg time="20:57" route_id="8" stop_id="101" serial="1"/>
<leg time="21:01" route_id="8" stop_id="59" serial="2"/>
...
</variant>
<variant var="4,5">
... more leg elements
</variant>
</track>
<track name="trackname2" variants="1,2,3,4,5,6,7">
<variant var="1">
... more leg elements
</variant>
<variant var="2,3,4,5,7">
... more leg elements
</variant>
</track>
</tracks>
Run Code Online (Sandbox Code Playgroud)
我将它导入到 Pandas 中,因为我需要能够将这些数据与其他 DataFrame 连接起来,并且我需要能够查询诸如“获取 route_id 5 的变体 1 的所有支路”之类的内容。
我想弄清楚我将如何在 Pandas DataFrame 中做到这一点。我应该制作一个看起来像这样的 DataFrame 吗:
track_name variants time route_id stop_id serial
"trackname1" "1,2,3" "21:23" "5" "103" "1"
"trackname1" "1,2,3" "21:26" "5" "17" "2"
...
"trackname1" "4,5" "21:20" "5" "103" "1"
...
"trackname2" "1" "20:59" "3" "45" "1"
... you get the point
Run Code Online (Sandbox Code Playgroud)
如果这是要走的路,我将如何(有效地)提取例如“route_id 5 上变体 3 的所有行”?请注意,这应该为我提供变体列列表中具有 3 的所有行,而不仅仅是变体列中只有“3”的行。
是否有不同的方式来构建 DataFrame 可以使这更容易?我应该使用熊猫以外的东西吗?
假设您有足够的内存,如果您的 DataFrame 每行保存一个变体,您的任务将更容易完成:
track_name variants time route_id stop_id serial
"trackname1" 1 "21:23" 5 103 1
"trackname1" 2 "21:23" 5 103 1
"trackname1" 3 "21:23" 5 103 1
"trackname1" 1 "21:26" 5 17 2
"trackname1" 2 "21:26" 5 17 2
"trackname1" 3 "21:26" 5 17 2
...
"trackname1" 4 "21:20" 5 103 1
"trackname1" 5 "21:20" 5 103 1
...
"trackname2" 1 "20:59" 3 45 1
Run Code Online (Sandbox Code Playgroud)
然后你可以找到“route_id 5 上变体 3 的所有行
df.loc[(df['variants']==3) & (df['route_id']==5)]
Run Code Online (Sandbox Code Playgroud)
如果将许多变体打包到一行中,例如
"trackname1" "1,2,3" "21:23" "5" "103" "1"
Run Code Online (Sandbox Code Playgroud)
那么你可以使用找到这样的行
df.loc[(df['variants'].str.contains("3")) & (df['route_id']=="5")]
Run Code Online (Sandbox Code Playgroud)
假设变体始终是个位数。如果还有“13”或“30”等 2 位数字变体,那么您需要将更复杂的正则表达式模式传递给str.contains.
或者,您可以使用apply逗号分隔每个变体:
df['variants'].apply(lambda x: "3" in x.split(','))
Run Code Online (Sandbox Code Playgroud)
但这是非常低效的,因为您现在将为每一行调用一次 Python 函数,并与矢量化整数比较相比进行字符串分割和列表中的成员资格测试。
因此,为了避免可能复杂的正则表达式或相对较慢的调用apply,我认为最好的选择是构建每行一个整数变体的 DataFrame。