pd.read_csv()错误地截断在Excel中格式化为科学记数法的时间戳

时间:2017-12-14 18:33:35

标签: python excel pandas csv timestamp

我有一个csv格式的数据集,可以自动从Web服务下载。 csv文件具有以下通用格式:

csv file in excel
[Timestamp]  [Column B]
1.51258E+12  A
1.51242E+12  B
1.51242E+12  C

在' General'中更改['Timestamp']格式。到' Number',完整的数字显示如下:

csv file (formatting changed in excel)
[Timestamp]   [Column B]
1512584017891  A
1512423886571  B
1512423818970  C

我需要自动处理csv文件,所以每次都不能在excel中进入文件,将格式从一般转换为时间戳。我发现pd.read_csv()正在将['Timestamp'] csv列作为科学记数法导入,留下截断的df['Timestamp'] dtype=float64

df (in pandas)
[Timestamp]  [Column B]
1.512580e+12  A
1.512420e+12  B
1.512420e+12  C

注意现在df['Timestamp']在导入时如何在E + 12之前添加0。我试图转换df['Timestamp'].astype('int64'),但这表明我担心的是:pd.read_csv()将隐藏的数字替换为零。

In[1]: df['Timestamp'].astype('int64').head(3)

Out[1]: 1512580000000
        1512420000000
        1512420000000
        Name: Timestamp, dtype: int64

有没有办法1)导入正确的时间戳,然后2)将时间戳转换为以下格式:12/14/2017 10:32:12 AM?

3 个答案:

答案 0 :(得分:0)

您可以使用pd.read_csv选项dtype来指示每列的数据类型。这应该避免数据丢失从大熊猫的默认解释开始,然后在你已经读入数据后进行转换:

df = pd.read_csv('fname.csv', dtype = {'Timestamp': np.int64})

答案 1 :(得分:0)

In the below answer, I have tried using pandas.to_datetime, to convert 
the epoch time into date time.
I'm reading data from csv like below:

import pandas as pd
df = pd.read_csv(path) 
print(df) 

      Timestamp
0  1.512580e+12
1  1.512420e+12
2  1.512420e+12

df.Timestamp = pd.to_datetime(df['Timestamp'], unit='ms')
print(df)

            Timestamp
0 2017-12-06 17:06:40
1 2017-12-04 20:40:00
2 2017-12-04 20:40:00


df.applymap(type)


Timestamp
0   <class 'pandas._libs.tslib.Timestamp'>
1   <class 'pandas._libs.tslib.Timestamp'>
2   <class 'pandas._libs.tslib.Timestamp'>

答案 2 :(得分:0)

可能有办法让pandas正确读取您的数据。但是我不知道如何知道如何。

我所知道的是,Python为您提供了自己控制读取和数据转换的关键部分的工具(这样您就不会怜悯pandas执行的隐式转换和可能有损转换)。

在评论中,您说原始下载的CSV包含在文本编辑器中查看时的所有时间戳数字。所以,让我们说原始数据看起来像这样:

1512584017891,A
1512423886571,B
1512423818970,C

您可以使用普通Python读取数据,如下所示:

with open('myfile.csv') as f:
    for line in f:
        print(line.strip().split(','))

(如果原始CSV较大或较复杂,或者可能存在“麻烦”字符,例如作为数据一部分的逗号,而不仅仅是分隔符,那么您将需要使用csv模块而不是简单地拆分所有逗号。)

以上产生

['1512584017891', 'A']
['1512423886571', 'B']
['1512423818970', 'C']

所以你看,你有所有的数字。您可以使用内置的int函数将这些数字无损地转换为Python整数(具有任意精度),或者使用内置的float函数将这些数字无损转换为Python浮点数(IEEE双精度数)。例如,如果我们从原始CSV输入重新开始:

with open('myfile.csv') as f:
    for line in f:
        tokens = line.strip().split(',')
        ms = int(tokens[0])  # my guess is you have milliseconds
        label = tokens[1]
        print([ms, label])

打印出来

[1512584017891, 'A']
[1512423886571, 'B']
[1512423818970, 'C']

你知道我要去哪儿吗?也许这是将数据传递给大熊猫的合适位置,也许不是。你可以用普通的Python继续下去,并推迟控制pandas:

import time

with open('myfile.csv') as f:
    for line in f:
        tokens = line.strip().split(',')
        secs = int(tokens[0]) * 0.001
        label = tokens[1]
        print([time.ctime(secs), label])

以上产生

['Wed Dec  6 13:13:37 2017', 'A']
['Mon Dec  4 16:44:46 2017', 'B']
['Mon Dec  4 16:43:38 2017', 'C']

请注意time.ctime的输出是一个格式化的字符串,它会截断一秒的分数。如果你想要一个合适的Python“时间戳”(保留到微秒,如果可用的话),最好使用datetime

from datetime import datetime

with open('myfile.csv') as f:
    for line in f:
        tokens = line.strip().split(',')
        secs = int(tokens[0]) * 0.001
        label = tokens[1]
        print([datetime.fromtimestamp(secs), label])

产生

[datetime.datetime(2017, 12, 6, 13, 13, 37, 891000), 'A']
[datetime.datetime(2017, 12, 4, 16, 44, 46, 571000), 'B']
[datetime.datetime(2017, 12, 4, 16, 43, 38, 970000), 'C']

一旦你拥有一个合适的datetime对象,就可以用它来做很多事情,包括选择一个根据你自己的规范格式化的字符串,或用它做计算。将datetime个对象传递给大熊猫也是安全的,我不知道。

重点是,无论大熊猫失败了,您都可以选择使用Python及其标准库自行处理。

最后,既然你说你想最终结束另一个CSV作为你的输出:我认为值得一提的是,如果 CSV意味着人类使用Excel打开(或者LibreOffice或其他),然后考虑做一个帮助,直接输出到.xlsx文件。为此,您可以再次使用pandas或XlsxWriter等“低级”包。 (这不是很低级,但它比熊猫级低。事实上,它是由 pandas使用,但你可以直接使用它来获得更多控制和更丰富的功能。)