如何将带有 if 语句的 for 循环的结果添加到我的数据框?
How can I add results of a for loop with an if statement to my dataframe?
我是 python 的新手,我无法将 loop/appending 结果返回到原始数据框。基本上,我有一个正在读入 python 的 csv,它有鱼检测时间。我希望能够将鱼类检测分类为白天或夜间。我正在使用带有 if 语句的 Astral 包,以显示是否在 'Day' 或 'Night' 检测到鱼,具体取决于一年中的特定位置和时间 sunrise/sunset。
我不确定我的循环是否过于复杂,但在与 NOAA 核实后,day/night 时间似乎是正确的。如何将 if 语句中的这些数据添加回我只有 DetectTime 的原始数据框中?
如果我想为附加列添加另一个 for 循环,使用 Astral 中的 dusk 和 dawn,我如何将它添加到数据帧,以便最终的 df 是 DetectTime、DayNight 和 DawnDusk?蒂亚!
import astral
from astral import sun
import pandas as pd
df = pd.read_csv("fishdata.csv", sep = '\t')
obs = astral.Observer(latitude = 30.128, longitude = -115.455, elevation = 0.0)
df['DetectTime'] = pd.to_datetime((df['DetectTime']))
df.DetectTime= df.DetectTime.dt.tz_localize('UTC').dt.tz_convert('Etc/GMT+8')
df = pd.DataFrame(df)
for data in df.DetectTime:
date = pd.to_datetime(data.strftime("%m/%d/%Y %H:%M"))
daylight = pd.to_datetime((sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')))
if pd.to_datetime(daylight[0].strftime("%m/%d/%Y %H:%M")) <= date < pd.to_datetime(daylight[1].strftime("%m/%d/%Y %H:%M")):
print(date, 'Day')
else: print(date, 'Night')
您不需要使用 for
循环。尝试使用 apply()
.
方法一:
# Create sample data
df = pd.DataFrame([pd.Timestamp('2014-01-23 00:00:00', tz='UTC'), pd.Timestamp('2014-01-23 12:00:00', tz='UTC')], columns=['DetectTime'])
df.DetectTime = df.DetectTime.dt.tz_convert('Etc/GMT+8')
# Determine day or night
df['day_or_night'] = df.DetectTime.apply(lambda date: 'Day' if sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')[0] <= date.to_pydatetime() < sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')[1] else 'Night')
输出:
print(df)
DetectTime day_or_night
0 2014-01-22 16:00:00-08:00 Day
1 2014-01-23 04:00:00-08:00 Night
方法二:
另一种方法是将sun.daylight
分成两列,然后使用eval()
。此方法产生相同的结果,但使您的代码更易于阅读。
df['range1'] = df.DetectTime.apply(lambda x: sun.daylight(obs, x, tzinfo = 'Etc/GMT+8')[0])
df['range2'] = df.DetectTime.apply(lambda x: sun.daylight(obs, x, tzinfo = 'Etc/GMT+8')[1])
df['day_or_night'] = df.eval('range1 <= DetectTime < range2')
输出:
print(df)
DetectTime range1 range2 day_or_night
0 2014-01-22 16:00:00-08:00 2014-01-22 06:37:10.514609-08:00 2014-01-22 17:10:03.436729-08:00 True
1 2014-01-23 04:00:00-08:00 2014-01-23 06:36:49.146199-08:00 2014-01-23 17:10:56.041892-08:00 False
我是 python 的新手,我无法将 loop/appending 结果返回到原始数据框。基本上,我有一个正在读入 python 的 csv,它有鱼检测时间。我希望能够将鱼类检测分类为白天或夜间。我正在使用带有 if 语句的 Astral 包,以显示是否在 'Day' 或 'Night' 检测到鱼,具体取决于一年中的特定位置和时间 sunrise/sunset。
我不确定我的循环是否过于复杂,但在与 NOAA 核实后,day/night 时间似乎是正确的。如何将 if 语句中的这些数据添加回我只有 DetectTime 的原始数据框中?
如果我想为附加列添加另一个 for 循环,使用 Astral 中的 dusk 和 dawn,我如何将它添加到数据帧,以便最终的 df 是 DetectTime、DayNight 和 DawnDusk?蒂亚!
import astral
from astral import sun
import pandas as pd
df = pd.read_csv("fishdata.csv", sep = '\t')
obs = astral.Observer(latitude = 30.128, longitude = -115.455, elevation = 0.0)
df['DetectTime'] = pd.to_datetime((df['DetectTime']))
df.DetectTime= df.DetectTime.dt.tz_localize('UTC').dt.tz_convert('Etc/GMT+8')
df = pd.DataFrame(df)
for data in df.DetectTime:
date = pd.to_datetime(data.strftime("%m/%d/%Y %H:%M"))
daylight = pd.to_datetime((sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')))
if pd.to_datetime(daylight[0].strftime("%m/%d/%Y %H:%M")) <= date < pd.to_datetime(daylight[1].strftime("%m/%d/%Y %H:%M")):
print(date, 'Day')
else: print(date, 'Night')
您不需要使用 for
循环。尝试使用 apply()
.
方法一:
# Create sample data
df = pd.DataFrame([pd.Timestamp('2014-01-23 00:00:00', tz='UTC'), pd.Timestamp('2014-01-23 12:00:00', tz='UTC')], columns=['DetectTime'])
df.DetectTime = df.DetectTime.dt.tz_convert('Etc/GMT+8')
# Determine day or night
df['day_or_night'] = df.DetectTime.apply(lambda date: 'Day' if sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')[0] <= date.to_pydatetime() < sun.daylight(obs, date, tzinfo = 'Etc/GMT+8')[1] else 'Night')
输出:
print(df)
DetectTime day_or_night
0 2014-01-22 16:00:00-08:00 Day
1 2014-01-23 04:00:00-08:00 Night
方法二:
另一种方法是将sun.daylight
分成两列,然后使用eval()
。此方法产生相同的结果,但使您的代码更易于阅读。
df['range1'] = df.DetectTime.apply(lambda x: sun.daylight(obs, x, tzinfo = 'Etc/GMT+8')[0])
df['range2'] = df.DetectTime.apply(lambda x: sun.daylight(obs, x, tzinfo = 'Etc/GMT+8')[1])
df['day_or_night'] = df.eval('range1 <= DetectTime < range2')
输出:
print(df)
DetectTime range1 range2 day_or_night
0 2014-01-22 16:00:00-08:00 2014-01-22 06:37:10.514609-08:00 2014-01-22 17:10:03.436729-08:00 True
1 2014-01-23 04:00:00-08:00 2014-01-23 06:36:49.146199-08:00 2014-01-23 17:10:56.041892-08:00 False