【问题标题】:Correct way of iterating over pandas dataframe by date按日期迭代熊猫数据框的正确方法
【发布时间】:2014-06-16 05:25:24
【问题描述】:

我想按日期迭代数据框的主轴日期。

示例:

tdf = df.ix[date]

我遇到的问题是 df.ix 返回的类型发生了变化,给我留下了 3 种可能的情况

  1. 如果tdf 中不存在日期,则会引发错误:KeyError: 1394755200000000000

  2. 如果tdf 中只有一项:print type(tdf) 返回 <class 'pandas.core.series.Series'>

  3. 如果tdf 中有多个项目:print type(tdf) 返回 <class 'pandas.core.frame.DataFrame'>

为了避免第一种情况,我可以简单地将其包装在 try catch 块中,或者感谢 jxstanford,我可以使用 if date in df.index: 避免 try catch 块

后来我遇到了这个问题,API 与 pandas 系列和 pandas 数据框不一致。我可以通过检查类型来解决这个问题,但似乎我不应该这样做。理想情况下,我希望保持类型相同。有更好的方法吗?

我正在运行 pandas 0.13.1,我目前正在使用 CSV 从 CSV 加载数据

这是一个演示问题的完整示例。

from pandas import DataFrame
import datetime

path_to_csv = '/home/n/Documents/port/test.csv'

df = DataFrame.from_csv(path_to_csv, index_col=3, header=0, parse_dates=True, sep=',')

start_dt = df.index.min()
end_dt = df.index.max()
dt_step = datetime.timedelta(days=1)

df.sort_index(inplace=True)

cur_dt = start_dt

while cur_dt != end_dt:
    if cur_dt in df.index:
       print type(df.ix[cur_dt])
    #run some other steps using cur_dt

    cur_dt += dt_step

演示该问题的示例 CSV 如下:

value1,value2,value3,Date,type
1,2,4,03/13/14,a
2,3,3,03/21/14,b
3,4,2,03/21/14,a
4,5,1,03/27/14,b

上面的代码打印出来

<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>

是否可以以一致的方式从 tdf 获取 value1 的值?还是我坚持为每个案例做一个 if 语句并分别处理?

if type(df.ix[cur_dt]) == DataFrame:
    ....
if type(df.ix[cur_dt]) == Series:
    ....

【问题讨论】:

  • 您可以使用unique 获得所有日期的唯一列表,然后遍历该列表。
  • @KarlD。我需要其他所有日期,而不仅仅是数据框中缺少许多日期的唯一值。
  • 尝试使用 DataFrame.from_csv 而不是 pandas.read_csv。这可能有助于解决您的问题 2 和 3。
  • 你真的必须提供更多的细节,一个初学者的玩具数据集。你得到的行为是预期的:如果你提取一行,你得到一个系列(一维数组),如果你提取多行,它是一个 DataFrame(二维数组)。如果你告诉 pandas 寻找不存在的东西,它会给你一个错误。如果你解释你想要的结果是什么(一列?更多列?),那么有一些方法可以处理所有这些问题。
  • @jxstanford 谢谢我试过你的建议我仍然遇到同样的问题,

标签: pandas dataframe iteration


【解决方案1】:

不确定您要对数据框做什么,但这可能比尝试/例外更好:

tdf = DataFrame.from_csv(path_to_csv, index_col=3, header=0, parse_dates=True, sep=',')
while cur_dt != end_dt:
    if cur_dt in df.index:
       # do your thing

    cur_dt += dt_step

【讨论】:

  • 这确实有帮助!但我遇到其他问题我会更新问题
【解决方案2】:

您可以使用DataFrameapply方法,使用axis = 1处理DataFrame的每一行来构建一个Series 具有相同的索引

例如

def calculate_value(row):
   if row.date == pd.datetime(2014,3,21):
      return 0
   elif row.type == 'a':
      return row.value1 + row.value2 + row.value3
   else:
      return row.value1 * row.value2 * row.value3

df['date'] = df.index
df['NewValue'] = df.apply(calculate_value, axis=1)

如下修改您的示例输入

            value1  value2  value3 type  NewValue       date
Date
2014-03-13       1       2       4    a         7 2014-03-13
2014-03-21       2       3       3    b         0 2014-03-21
2014-03-21       3       4       2    a         0 2014-03-21
2014-03-27       4       5       1    b        20 2014-03-27

[4 rows x 6 columns]

【讨论】:

    【解决方案3】:

    这个玩具代码将一致地返回 DataFrames。

    def framer(rows):
        if ndim(rows) == 1:
            return rows.to_frame().T
        else:
            return rows
    
    for cur_date in df.index:
        print type(framer(df.ix[cur_date]))
    

    这会给你缺少的日子:

    df.resample(rule='D')
    

    查看重采样方法文档字符串。它有自己的选项来填补缺失的数据。如果您决定将多个日期合并为一个日期,您正在查看的方法是 groupby(如果您想跨行组合值)和 drop_duplicates(如果你想忽略它们)。无需重新发明轮子。

    【讨论】:

      猜你喜欢
      • 2013-10-23
      • 2020-05-17
      • 2015-12-09
      • 1970-01-01
      • 2013-12-24
      • 2017-05-16
      • 2018-03-07
      • 1970-01-01
      • 2013-01-08
      相关资源
      最近更新 更多