在我使用的数据索引是复合 - 即它有项目名称和时间戳,例如name@domain.com|2013-05-07 05:52:51 +0200.
我想进行分层索引,以便将相同的电子邮件组合在一起,因此我需要将DataFrame索引转换为MultiIndex(例如,用于上面的条目 - (name@domain.com, 2013-05-07 05:52:51 +0200)).
这样做最方便的方法是什么?
Pio*_*dal 11
一旦我们有了DataFrame
import pandas as pd
df = pd.read_csv("input.csv", index_col=0) # or from another source
Run Code Online (Sandbox Code Playgroud)
和一个函数将每个索引映射到一个元组(下面,它是这个问题的例子)
def process_index(k):
return tuple(k.split("|"))
Run Code Online (Sandbox Code Playgroud)
我们可以通过以下方式创建分层索引:
df.index = pd.MultiIndex.from_tuples([process_index(k) for k,v in df.iterrows()])
Run Code Online (Sandbox Code Playgroud)
另一种方法是创建两列,然后将它们设置为索引(原始索引将被删除):
df['e-mail'] = [x.split("|")[0] for x in df.index]
df['date'] = [x.split("|")[1] for x in df.index]
df = df.set_index(['e-mail', 'date'])
Run Code Online (Sandbox Code Playgroud)
甚至更短
df['e-mail'], df['date'] = zip(*map(process_index, df.index))
df = df.set_index(['e-mail', 'date'])
Run Code Online (Sandbox Code Playgroud)
我的偏好是最初将其作为列(即不是索引)读取,然后您可以使用 str split 方法:
csv = '\n'.join(['name@domain.com|2013-05-07 05:52:51 +0200, 42'] * 3)
df = pd.read_csv(StringIO(csv), header=None)
In [13]: df[0].str.split('|')
Out[13]:
0 [name@domain.com, 2013-05-07 05:52:51 +0200]
1 [name@domain.com, 2013-05-07 05:52:51 +0200]
2 [name@domain.com, 2013-05-07 05:52:51 +0200]
Name: 0, dtype: object
Run Code Online (Sandbox Code Playgroud)
然后将其输入 MultiIndex(也许这可以做得更干净?):
m = pd.MultiIndex.from_arrays(zip(*df[0].str.split('|')))
Run Code Online (Sandbox Code Playgroud)
删除第 0 列并将索引设置为新的 MultiIndex:
del df[0]
df.index = m
In [17]: df
Out[17]:
1
name@domain.com 2013-05-07 05:52:51 +0200 42
2013-05-07 05:52:51 +0200 42
2013-05-07 05:52:51 +0200 42
Run Code Online (Sandbox Code Playgroud)
在pandas>=0.16.0,我们可以.str在索引上使用访问器.这使得以下可能:
df.index = pd.MultiIndex.from_tuples(df.index.str.split('|').tolist())
Run Code Online (Sandbox Code Playgroud)
(注意:我尝试的更直观:pd.MultiIndex.from_arrays(df.index.str.split('|'))但由于某种原因,这给了我错误.)
| 归档时间: |
|
| 查看次数: |
10317 次 |
| 最近记录: |