Eri*_*own 10 python csv pandas
我有一个包含许多列的csv文件.使用pandas,我将这个csv文件读入一个数据帧,并有一个日期时间索引和五到六个其他列.
其中一列是时间戳列表(下面带索引的示例)
CreateDate TimeStamps
4/1/11 [Timestamp('2012-02-29 00:00:00'), Timestamp('2012-03-31 00:00:00'), Timestamp('2012-04-25 00:00:00'), Timestamp('2012-06-30 00:00:00')]
4/2/11 [Timestamp('2014-01-31 00:00:00')]
6/8/11 [Timestamp('2012-08-31 00:00:00'), Timestamp('2012-09-30 00:00:00'), Timestamp('2012-11-07 00:00:00'), Timestamp('2013-01-10 00:00:00'), Timestamp('2013-07-25 00:00:00')]
Run Code Online (Sandbox Code Playgroud)
我想要做的是将时间戳列转换为列出的每个时间戳的单独行.例如,对于第1行,它将转换为4行,第2行将转换为1行.我意识到我需要重置索引才能做到这一点,这很好.
我尝试过的所有东西最终都会进入左侧区域(获取值并在熊猫之外创建一个列表等)
任何建议赞赏.
cwh*_*and 12
如果你想留在纯大熊猫中,你可能会陷入困境groupby,apply如果不计算列重命名,最终会沸腾到一个衬里.
In [1]: import pandas as pd
In [2]: d = {'date': ['4/1/11', '4/2/11'], 'ts': [[pd.Timestamp('2012-02-29 00:00:00'), pd.Timestamp('2012-03-31 00:00:00'), pd.Timestamp('2012-04-25 00:00:00'), pd.Timestamp('2012-06-30 00:00:00')], [pd.Timestamp('2014-01-31 00:00:00')]]}
In [3]: df = pd.DataFrame(d)
In [4]: df.head()
Out[4]:
date ts
0 4/1/11 [2012-02-29 00:00:00, 2012-03-31 00:00:00, 201...
1 4/2/11 [2014-01-31 00:00:00]
In [5]: df_new = df.groupby('date').ts.apply(lambda x: pd.DataFrame(x.values[0])).reset_index().drop('level_1', axis = 1)
In [6]: df_new.columns = ['date','ts']
In [7]: df_new.head()
Out[7]:
date ts
0 4/1/11 2012-02-29
1 4/1/11 2012-03-31
2 4/1/11 2012-04-25
3 4/1/11 2012-06-30
4 4/2/11 2014-01-31
Run Code Online (Sandbox Code Playgroud)
由于目标是获取列的值(在本例中为date)并对要从列表中创建的多行的所有值重复它,因此考虑pandas索引是有用的.
我们希望日期成为新行的单个索引,因此我们使用groupby它将所需的行值放入索引中.然后在该操作中我想仅拆分这个日期的列表,这将是我们apply将要做的.
我正在传递apply一个Series由单个列表组成的熊猫,但是我可以通过将该列表.values[0]的唯一行推Series送到具有单个条目的数组来访问该列表.
要将列表转换为一组将传递回索引日期的行,我可以将其设置为a DataFrame.这导致了获得额外指数的惩罚,但我们最终放弃了.我们可以将其作为索引本身,但这将排除重复值.
一旦传回这个,我有一个多索引,但我可以将其强制为我们想要的行格式reset_index.然后我们简单地删除不需要的索引.
这听起来很复杂,但实际上我们只是利用pandas函数的自然行为来避免显式迭代或循环.
速度方面,这往往是相当不错的,因为它依赖于apply任何与此同时工作的并行化技巧apply.
(可选)如果您希望它对多个日期都很健壮,每个日期都有一个嵌套列表:
df_new = df.groupby('date').ts.apply(lambda x: pd.DataFrame([item for sublist in x.values for item in sublist]))
Run Code Online (Sandbox Code Playgroud)
在这一点上,一个衬管变得密集,你应该投入一个功能.
我这样做的方法是将列表拆分成单独的列,然后melt编辑它以将每个时间戳放在一个单独的行中.
In [48]: df = pd.DataFrame([[1,2,[1,2,4]],[4,5,[1,3]],],columns=['a','b','TimeStamp'])
...: df
Out[48]:
a b TimeStamp
0 1 2 [1, 2, 4]
1 4 5 [1, 3]
Run Code Online (Sandbox Code Playgroud)
您可以将列转换为列表,然后返回到a DataFrame以将其拆分为列:
In [53]: TScolumns = pd.DataFrame(df.TimeStamp.tolist(), )
...: TScolumns
Out[53]:
0 1 2
0 1 2 4
1 1 3 NaN
Run Code Online (Sandbox Code Playgroud)
然后将其拼接到原始数据帧上
In [90]: df = df.drop('TimeStamp',axis=1)
In [58]: split = pd.concat([df, TScolumns], axis=1)
...: split
Out[58]:
a b 0 1 2
0 1 2 1 2 4
1 4 5 1 3 NaN
Run Code Online (Sandbox Code Playgroud)
最后,用melt它将它变成你想要的形状:
In [89]: pd.melt(split, id_vars=['a', 'b'], value_name='TimeStamp')
Out[89]:
a b variable TimeStamp
0 1 2 0 1
1 4 5 0 1
2 1 2 1 2
3 4 5 1 3
4 1 2 2 4
5 4 5 2 NaN
Run Code Online (Sandbox Code Playgroud)
这感觉不太Pythonic,但它有效(前提是你的createDate是唯一的!)
Apply 只会返回比使用 groupby 获得的行数更多的行,因此我们将人为地使用 groupby (即 groupby 一列唯一值,因此每个组都是一行)。
def splitRows(x):
# Extract the actual list of time-stamps.
theList = x.TimeStamps.iloc[0]
# Each row will be a dictionary in this list.
listOfNewRows = list()
# Iterate over items in list of timestamps,
# putting each one in a dictionary to later convert to a row,
# then adding the dictionary to a list.
for i in theList:
newRow = dict()
newRow['CreateDate'] = x.CreateDate.iloc[0]
newRow['TimeStamps'] = i
listOfNewRows.append(newRow)
# Now convert these dictionaries into rows in a new dataframe and return it.
return pd.DataFrame(listOfNewRows)
df.groupby('CreateDate', as_index = False, group_keys = False).apply(splitRows)
Run Code Online (Sandbox Code Playgroud)
后续:如果 CreateDate 不唯一,您可以将索引重置为新列并对其进行分组。
| 归档时间: |
|
| 查看次数: |
12533 次 |
| 最近记录: |