如何将带有 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。

  1. 我不确定我的循环是否过于复杂,但在与 NOAA 核实后,day/night 时间似乎是正确的。如何将 if 语句中的这些数据添加回我只有 DetectTime 的原始数据框中?

  2. 如果我想为附加列添加另一个 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