我是R背景的Python /熊猫新手。我在理解如何处理现有列以根据现有列的多个条件创建新列时遇到麻烦。有10个不同的条件需要满足,但为简单起见,我将使用2种情况。
在R中:
install.packages("lubridate")
library(lubridate)
df <- data.frame("Date" = c("2020-07-01", "2020-07-15"))
df$Date <- as.Date(df$Date, format = "%Y-%m-%d")
df$Fiscal <- ifelse(day(df$Date) > 14,
paste0(year(df$Date),"-",month(df$Date) + 1,"-01"),
paste0(year(df$Date),"-",month(df$Date),"-01")
)
df$Fiscal <- as.Date(df$Fiscal, format = "%Y-%m-%d")
在Python中,我有:
import pandas as pd
import datetime as dt
df = {'Date': ['2020-07-01', '2020-07-15']}
df = pd.DataFrame(df)
df['Date'] = pd.to_datetime(df['Date'], yearfirst = True, format = "%Y-%m-%d")
df.loc[df['Date'].dt.day > 14,
'Fiscal'] = "-".join([dt.datetime.strftime(df['Date'].dt.year), dt.datetime.strftime(df['Date'].dt.month + 1),"01"])
df.loc[df['Date'].dt.day <= 14,
'Fiscal'] = "-".join([dt.datetime.strftime(df['Date'].dt.year), dt.datetime.strftime(df['Date'].dt.month),"01"])
如果我不转换'Date'字段,它说它期望一个字符串,但是,如果我确实转换了date字段,我仍然会收到错误,因为它似乎适用于'Series'对象。 / p>
TypeError: descriptor 'strftime' for 'datetime.date' objects doesn't apply to a 'Series' object
我知道我可能有一些术语或概念不正确并表示歉意,但是我看到的关于创建具有多个条件的新列的答案似乎并没有操纵他们正在检查条件的现有列,而只是根据指定的值。我只能想象有一种更有效的方法来减少“ R-ey”,但是我不确定从哪里开始。
答案 0 :(得分:1)
这并不是一个完整的答案,就像{em>插图 strftime
的工作原理一样:strftime
是date(time)
对象的一种方法,它采用格式字符串作为参数:
import pandas as pd
import datetime as dt
df = {'Date': ['2020-07-01', '2020-07-15']}
df = pd.DataFrame(df)
df['Date'] = pd.to_datetime(df['Date'], yearfirst = True, format = "%Y-%m-%d")
s = [dt.date(df['Date'][i].year, df['Date'][i].month + 1, 1).strftime('%Y-%m-%d')
for i in df['Date'].index]
print(s)
结果:
['2020-08-01', '2020-08-01']
再次:没有完整的答案,只是一个提示。
编辑:您可以对此进行矢量化,例如:
import pandas as pd
import datetime as dt
df = {'Date': ['2020-07-01', '2020-07-15']}
df = pd.DataFrame(df)
df['Date'] = pd.to_datetime(df['Date'], yearfirst=True, format='%Y-%m-%d')
df['Fiscal'] = df['Date'].apply(lambda d: dt.date(d.year, d.month, 1)
if d.day < 15 else
dt.date(d.year, d.month + 1, 1))
print(df)
结果:
Date Fiscal
0 2020-07-01 2020-07-01
1 2020-07-15 2020-08-01
这里我正在使用即时lambda
函数。您也可以使用外部定义的函数来做到这一点:
def to_fiscal(date):
if date.day < 15:
return dt.date(date.year, date.month, 1)
return dt.date(date.year, date.month + 1, 1)
df['Fiscal'] = df['Date'].apply(to_fiscal)
通常,矢量化比循环遍历更好,因为循环是在“更低”的水平上完成的,并且效率更高。
答案 1 :(得分:0)
直到有人告诉我,否则我将以这种方式进行。如果有一种方法可以将其向量化(或者通常来说是一种更好的方法),我将不胜感激
import pandas as pd
import datetime as dt
df = {'Date': ['2020-07-01', '2020-07-15']}
df = pd.DataFrame(df)
df['Date'] = pd.to_datetime(df['Date'], yearfirst=True, format='%Y-%m-%d')
test_list = list()
for i in df['Date'].index:
mth = df['Date'][i].month
yr = df['Date'][i].year
dy = df['Date'][i].day
if(dy > 14):
new_date = dt.date(yr, mth + 1, 1)
else:
new_date = dt.date(yr, mth, 1)
test_list.append(new_date)
df['New_Date'] = test_list