Pandas DataFrame中单列有多个值

8

我有一些数据需要从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>

我正在将此导入pandas,因为我需要能够将此数据与其他DataFrame连接,并且我需要能够查询类似于“获取route_id 5的变体1的所有legs”的内容。
我正在尝试弄清楚如何在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

如果这是正确的方法,我该如何(高效地)提取例如“路线id为5上3号变体的所有行”?注意,这应该给我所有在变体列列表中具有3的行,而不仅仅是仅在变体列中有“3”的行。
是否有一种构建DataFrame的不同方法可以使这更容易?我应该使用除pandas之外的其他东西吗?
1个回答

5
假设您有足够的内存,如果您的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

然后,您可以找到“在route_id 5上与变体3相关的所有行。”

df.loc[(df['variants']==3) & (df['route_id']==5)]

如果您将许多变量打包到一行中,例如:
"trackname1"   "1,2,3"   "21:23"  "5"       "103"    "1"

那么你可以使用以下方法查找这些行:

df.loc[(df['variants'].str.contains("3")) & (df['route_id']=="5")]

假设变量总是单个数字。如果还有像“13”或“30”这样的两位数变量,则需要传递更复杂的正则表达式模式给str.contains
另外,您可以使用apply将每个变量拆分成逗号:
df['variants'].apply(lambda x: "3" in x.split(','))

但这样做非常低效,因为您现在将为每一行调用 Python 函数,并进行字符串拆分和测试成员资格列表与矢量化整数比较。

因此,为了避免可能复杂的正则表达式或相对较慢的 apply 调用,我认为最好的方法是使用每行一个整数变量构建 DataFrame。


1
谢谢。这基本上是我所希望的不是 :-/ 我可以通过在解析数据时执行该操作来避免字符串操作,而不是将字符串“1,2,3,5”插入变量列中,我会在解析期间拆分它并插入列表或元组。那将更有效率,但仍然有点混乱。我真的希望我能够拥有某种“多维列”或无论你如何称呼它们。 - StFS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接