【问题标题】:Using for loop to grab values of one column based on the value of another column使用 for 循环根据另一列的值获取一列的值
【发布时间】:2020-03-01 19:50:32
【问题描述】:

我试图根据另一列的值获取一列的所有值。 我已经发现了一些与我相关的有用的 stackoverflow 问题,但这些解决方案似乎不适用于可变范围。我需要为变量做一些不同的事情吗?

我试图只从数据集中获取“open”列的值,其中“month”的值等于循环中的月份变量。

需要明确的是,预期的输出只是“开放”值。

for year in dfClose['year'].unique():
        tempYearDF = dfClose[dfClose['year'] == year]
        for month in range(1,13):
            tempOpenDF = tempYearDF.loc[tempYearDF['month'] == month, 'open']

我计划在分配数据后对 tempOpenDF 变量进行更多操作,但我首先需要验证它是否正在填充。

样本数据

dfClose

    open      year  month   day    date
0   30.490000   2010    1   4   2010-01-04
1   30.657143   2010    1   5   2010-01-05
2   30.625713   2010    1   6   2010-01-06
3   30.250000   2010    1   7   2010-01-07
4   30.042856   2010    1   8   2010-01-08
.
.
2551    297.260010  2020    2   24  2020-02-24
2552    300.950012  2020    2   25  2020-02-25
2553    286.529999  2020    2   26  2020-02-26
2554    281.100006  2020    2   27  2020-02-27
2555    257.260010  2020    2   28  2020-02-28

输出

tempOpenDF
Series([], Name: open, dtype: float64)

数据类型

tempYearDF.dtypes

open     float64
year       int64
month      int64
day        int64
date      object
dtype: object

“年份”的所有数据都正确分离,只是现在无法获取月份数据。

tempYearDF

    open    year    month   day date
2516    296.239990  2020    1   2   2020-01-02
2517    297.149994  2020    1   3   2020-01-03
2518    293.790009  2020    1   6   2020-01-06
2519    299.839996  2020    1   7   2020-01-07
2520    297.160004  2020    1   8   2020-01-08
2521    307.239990  2020    1   9   2020-01-09
2522    310.600006  2020    1   10  2020-01-10
2523    311.640015  2020    1   13  2020-01-13
2524    316.700012  2020    1   14  2020-01-14
2525    311.850006  2020    1   15  2020-01-15
2526    313.589996  2020    1   16  2020-01-16
2527    316.269989  2020    1   17  2020-01-17
2528    317.190002  2020    1   21  2020-01-21
2529    318.579987  2020    1   22  2020-01-22
2530    317.920013  2020    1   23  2020-01-23
2531    320.250000  2020    1   24  2020-01-24
2532    310.059998  2020    1   27  2020-01-27
2533    312.600006  2020    1   28  2020-01-28
2534    324.450012  2020    1   29  2020-01-29
2535    320.540009  2020    1   30  2020-01-30
2536    320.929993  2020    1   31  2020-01-31
2537    304.299988  2020    2   3   2020-02-03
2538    315.309998  2020    2   4   2020-02-04
2539    323.519989  2020    2   5   2020-02-05
2540    322.570007  2020    2   6   2020-02-06
2541    322.369995  2020    2   7   2020-02-07
2542    314.179993  2020    2   10  2020-02-10
2543    323.600006  2020    2   11  2020-02-11
2544    321.470001  2020    2   12  2020-02-12
2545    324.190002  2020    2   13  2020-02-13
2546    324.739990  2020    2   14  2020-02-14
2547    315.359985  2020    2   18  2020-02-18
2548    320.000000  2020    2   19  2020-02-19
2549    322.630005  2020    2   20  2020-02-20
2550    318.619995  2020    2   21  2020-02-21
2551    297.260010  2020    2   24  2020-02-24
2552    300.950012  2020    2   25  2020-02-25
2553    286.529999  2020    2   26  2020-02-26
2554    281.100006  2020    2   27  2020-02-27
2555    257.260010  2020    2   28  2020-02-28

如果我也对等号使用实际值,我会得到我想要的结果。 但是当我尝试根据范围循环值使用该值时,它会中断。

不错

tempYearDF.loc[tempYearDF['month'] == 1, 'open']

2516    296.239990
2517    297.149994
2518    293.790009
2519    299.839996
2520    297.160004
2521    307.239990
2522    310.600006
2523    311.640015

【问题讨论】:

  • 你的预期输出是什么?
  • 仅开放值
  • 您能否发布一个示例 DataFrame,说明结果的外观?我看到了中间数据帧的例子,但没有明确的例子说明解决方案应该产生什么
  • 添加到问题底部

标签: python pandas for-loop


【解决方案1】:

你不能只group by 年份和月份然后从那里开始吗?

for _, v in df.groupby(['year', 'month'])['open']:
    tempOpenDF = v
    # do stuff

【讨论】:

  • 谢谢,这很有帮助,我会更多地研究它,对 python 还是有点新。我通过在月份变量周围添加引号解决了这个问题。
  • 你应该使用它而不是你的循环解决方案。通过使用循环来迭代数据框,您正在破坏使用数据框的目的
  • 在弄乱了这里的一堆建议之后,这似乎是最好的。谢谢大家!
【解决方案2】:

示例数据框:

     0     1  2
0  123  2020  1
1  234  2020  2
2  543  2020  1
# For all unique years
for y in df[1].unique():
    # For all unique months
    for m in df[2].unique():
        # Get the row based on the month
        row = df.loc[df[2] == m]
            # Print only the desired column
            print(row[0])

输出:

0    123
2    543
Name: 0, dtype: int64
1    234
Name: 0, dtype: int64

【讨论】:

    【解决方案3】:
    for month in range(1,13):
        tempOpenDF = tempYearDF.loc[tempYearDF['month'] == month, 'open']
    

    loc = 位置,或“命名”项目

    您可能想要iloc,但tempYearDF['month'] 不是一整列吗?
    您可能需要参考tempYearDF['month'].valuetempYearDF['month'].the_name_of_this_column(或任何适当的方法/属性)。


    df[df["month"] ==1] 是一个包含 21 行和所有列的切片 df.loc[df["month"] ==1] 也是一个有 21 行和所有列的切片 'df.loc[df["month"] ==1, "open" 确实在月份等于 1 时返回 open 列中的 21 行。

    你也在哪里保存这个? tempOpenDF for 循环内。它的值会随着循环的每个索引而变化。

    我将不得不看到更多它被传递到的地方。就目前而言,您可以正确过滤,但将过滤后的数据发送到任何地方。

    您所拥有的其他方式。

    import pandas as pd
    df = pd.read_csv("sample_data.csv",sep='\t',parse_dates=["date"])
    # sample data is what you provided above, using tab separation
    #
    
    some_year = 2020
    print(df.loc[df["month"] == 1, 'open'],'\n')
    print(df.loc[df["year"] == 2020, 'open'],'\n')
    # print(df.loc[(df["month"] == 1 and df["year"] == 2020), 'open'])
    
    for i in range(1,13):
        dfy = df.loc[df["year"] == 2020]
        mondata = dfy.loc[dfy["month"] == i, "open"]
        print("Month: ",i,'\n',mondata,"\n")
    

    >>> df.head()
    some_index open year month day date
    0 2516 296.239990 2020 1 2 2020-01-02
    1 2517 297.149994 2020 1 3 2020-01-03
    2 2518 293.790009 2020 1 6 2020-01-06
    3 2519 299.839996 2020 1 7 2020-01-07
    4 2520 297.160004 2020 1 8 2020-01-08
    真正的索引是 0,1 等。some_index 来自您的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 2011-10-02
      相关资源
      最近更新 更多