Python Pandas:pandas.to_datetime() 在日小于 13 时切换日和月

Oum*_*b10 14 python datetime series dataframe pandas

我编写了一个读取多个文件的代码,但是在我的一些文件中,当一天小于 13 时,日期时间会交换日和月,并且从第 13 天或以上的任何一天开始,即 13/06/11 仍然是正确的(DD/MM /YY)。我试图通过这样做来修复它,但它不起作用。

我的数据框看起来像这样:实际日期时间是从 12june2015 到 13june2015,当我将日期时间列作为字符串读取时,日期保持正确 dd/mm/yyyy

tmp                     p1 p2 
11/06/2015 00:56:55.060  0  1
11/06/2015 04:16:38.060  0  1
12/06/2015 16:13:30.060  0  1
12/06/2015 21:24:03.060  0  1
13/06/2015 02:31:44.060  0  1
13/06/2015 02:37:49.060  0  1
Run Code Online (Sandbox Code Playgroud)

但是当我将我的列的类型更改为日期时间列时,它会为小于 13 的每一天交换我的日期和月份。

输出:

print(df)
tmp                  p1 p2 
06/11/2015 00:56:55  0  1
06/11/2015 04:16:38  0  1
06/12/2015 16:13:30  0  1
06/12/2015 21:24:03  0  1
13/06/2015 02:31:44  0  1
13/06/2015 02:37:49  0  1
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

我遍历文件:

df = pd.read_csv(PATH+file, header = None,error_bad_lines=False , sep = '\t')
Run Code Online (Sandbox Code Playgroud)

然后当我的代码读完我所有的文件时,我将它们连接起来,问题是我的日期时间列需要是日期时间类型,所以当我通过 pd_datetime() 更改它的类型时,它会交换日期小于 13 的日期和月份.

转换我的日期时间列后,日期是正确的(字符串类型)

print(tmp) # as a result I get 11.06.2015 12:56:05 (11june2015)
Run Code Online (Sandbox Code Playgroud)

但是当我更改列类型时,我得到了这个:

tmp = pd.to_datetime(tmp, unit = "ns")
tmp = temps_absolu.apply(lambda x: x.replace(microsecond=0))
print(tmp) # I get 06-11-2016 12:56:05 (06november2015 its not the right date)
Run Code Online (Sandbox Code Playgroud)

问题是:当一天小于 13 时,我应该使用或更改什么命令来停止日和月交换?

更新 此命令交换我的专栏的所有天数和月数

tmp =  pd.to_datetime(tmp, unit='s').dt.strftime('%#m/%#d/%Y %H:%M:%S') 
Run Code Online (Sandbox Code Playgroud)

所以为了只交换不正确的日期,我写了一个条件:

for t in tmp:
        if (t.day < 13):
            t = datetime(year=t.year, month=t.day, day=t.month, hour=t.hour, minute=t.minute, second = t.second)
Run Code Online (Sandbox Code Playgroud)

但它也不起作用

Sco*_*ton 40

您可以dayfirstpd.to_datetime.

pd.to_datetime(df.tmp, dayfirst=True)
Run Code Online (Sandbox Code Playgroud)

输出:

0   2015-06-11 00:56:55
1   2015-06-11 04:16:38
2   2015-06-12 16:13:30
3   2015-06-12 21:24:03
4   2015-06-13 02:31:44
5   2015-06-13 02:37:49
Name: tmp, dtype: datetime64[ns]
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不是公认的答案?效果很好,谢谢! (2认同)

Oum*_*b10 1

好吧,我解决了我的问题,但在一种消耗内存的方法中,我首先将 tmp 列拆分为日期和时间列,然后将日期列重新拆分为日、月和年,这样我就可以查找小于的日期13 并替换为对应的月份

df['tmp'] = pd.to_datetime(df['tmp'], unit='ns')
df['tmp'] = df['tmp'].apply(lambda x: x.replace(microsecond=0))
df['date'] = [d.date() for d in df['tmp']]
df['time'] = [d.time() for d in df['tmp']]
df[['year','month','day']] = df['date'].apply(lambda x: pd.Series(x.strftime("%Y-%m-%d").split("-")))

df['day'] = pd.to_numeric(df['day'], errors='coerce')
df['month'] = pd.to_numeric(df['month'], errors='coerce')
df['year'] = pd.to_numeric(df['year'], errors='coerce')


#Loop to look for days less than 13 and then swap the day and month
for index, d in enumerate(df['day']):
        if(d <13): 
 df.loc[index,'day'],df.loc[index,'month']=df.loc[index,'month'],df.loc[index,'day'] 
Run Code Online (Sandbox Code Playgroud)

# 将系列转换为字符串类型以便合并它们

 df['day'] = df['day'].astype(str)
 df['month'] = df['month'].astype(str)
 df['year'] = df['year'].astype(str)
 df['date']=  pd.to_datetime(df[['year', 'month', 'day']])
 df['date'] = df['date'].astype(str)
 df['time'] = df['time'].astype(str)
Run Code Online (Sandbox Code Playgroud)

# 将时间、日期和地点结果合并到我们的列中

df['tmp'] =pd.to_datetime(df['date']+ ' '+df['time'])
Run Code Online (Sandbox Code Playgroud)

# 删除添加的列

df.drop(df[['date','year', 'month', 'day','time']], axis=1, inplace = True)
Run Code Online (Sandbox Code Playgroud)