【问题标题】:Subsetting out rows using pandas使用 pandas 对行进行子集化
【发布时间】:2020-09-18 03:24:24
【问题描述】:

我有两组数据帧:datamax,datamax2015 和 datamin,datamin2015。

数据片段:

print(datamax.head())
print(datamin.head())
print(datamax2015.head())
print(datamin2015.head())

Date           ID Element  Data_Value
0  2005-01-01  USW00094889    TMAX         156
1  2005-01-02  USW00094889    TMAX         139
2  2005-01-03  USW00094889    TMAX         133
3  2005-01-04  USW00094889    TMAX          39
4  2005-01-05  USW00094889    TMAX          33
         Date           ID Element  Data_Value
0  2005-01-01  USC00200032    TMIN         -56
1  2005-01-02  USC00200032    TMIN         -56
2  2005-01-03  USC00200032    TMIN           0
3  2005-01-04  USC00200032    TMIN         -39
4  2005-01-05  USC00200032    TMIN         -94
         Date           ID Element  Data_Value
0  2015-01-01  USW00094889    TMAX          11
1  2015-01-02  USW00094889    TMAX          39
2  2015-01-03  USW00014853    TMAX          39
3  2015-01-04  USW00094889    TMAX          44
4  2015-01-05  USW00094889    TMAX          28
         Date           ID Element  Data_Value
0  2015-01-01  USC00200032    TMIN        -133
1  2015-01-02  USC00200032    TMIN        -122
2  2015-01-03  USC00200032    TMIN         -67
3  2015-01-04  USC00200032    TMIN         -88
4  2015-01-05  USC00200032    TMIN        -155

对于datamax,datamax2015,我想比较它们的Data_Value列,并在datamax2015中创建一个数据框,其中Data_Value大于一年中同一天datamax中的所有条目。因此,预期的输出应该是一个数据框,其行从 2015-01-01 到 2015-12-31 但日期仅在 Data_Value 列中的值大于 @ 中的值时987654325@ datamax 数据框的列。

即 4 行和 1 到 364 列之间的任何内容,具体取决于上述条件。

我想要 datamin 和 datamin2015 数据帧的逆 (min)。

我已经尝试了以下代码:

upper = []
for row in datamax.iterrows():
    for j in datamax2015["Data_Value"]:
        if j > row["Data_Value"]:
            upper.append(row)
lower = []
for row in datamin.iterrows():
    for j in datamin2015["Data_Value"]:
        if j < row["Data_Value"]:
            lower.append(row)

谁能帮我看看我哪里出错了?

【问题讨论】:

  • 你能从数据帧(datamin、datamin2015 和 datamax、datamax2015)中发布一个 sn-p 吗?特别是,两对中的每一对中的数据帧是否总是具有相同的行数?
  • 不,一个的日期是 2005-2014,另一个只有 2015 年。是的会在上面做。
  • 谢谢。您能否还提供您发布的示例数据框的预期输出?与 datamax2015 中的哪些行相比,我不清楚 datamax 中的哪些行应该有 Data_Value 条目。 - 一年中的同一天?
  • @Jonas 是的,一年中的同一天。
  • @Jonas 请看我上面的修改。

标签: python pandas loops indexing subset


【解决方案1】:

此代码为数据管理器执行您想要的操作。尝试使其适应 datamax 对称情况 - 如果您遇到问题并乐于提供进一步帮助,请发表评论。

创建数据

from datetime import datetime
import pandas as pd

datamin = pd.DataFrame({"date": pd.date_range(start=datetime(2005, 1, 1), end=datetime(2015, 12, 31)), "Data_Value": 1})
datamin["day_of_year"] = datamin["date"].dt.dayofyear
# Set the value for the 4th day of the year higher in order for the desired result to be non-empty
datamin.loc[datamin["day_of_year"]==4, "Data_Value"] = 2 

datamin2015 = pd.DataFrame({"date": pd.date_range(start=datetime(2015, 1, 1), end=datetime(2015, 12, 31)), "Data_Value": 2})
datamin2015["day_of_year"] = datamin["date"].dt.dayofyear
# Set the value for the 4th day of the year lower in order for the desired result to be non-empty
datamin2015.loc[3, "Data_Value"] = 1

解决办法

df1 = datamin.groupby("day_of_year").agg({"Data_Value": "min"})
df2 = datamin2015.join(df1, on="day_of_year", how="left", lsuffix="2015")
lower = df2.loc[df2["Data_Value2015"]<df2["Data_Value"]]
lower

我们按一年中的日期对数据进行分组,以找到一年中每一天的所有年份的最小值(使用.dt.dayofyear)。然后我们将其与 datamin2015 连接,最后可以将 Data_Value2015 与 Data_Value 进行比较,以找到 2015 年 Data_Value 小于 datamin 中全年所有同一天的最小值的行的索引。

在上面的示例中,按照我设置数据框的方式,下部有 1 行。

【讨论】:

  • 为什么我们需要将一年中第 4 天的值设置得更高,以使期望的结果不为空?
  • 您不必在代码中执行此操作 - 我这样做只是为了轻松生成一个示例来演示:)
  • 只能使用带有 datetimelike 值的 .dt 访问器:我现在收到此错误?
  • 那么您可能需要转换您的Date 列:stackoverflow.com/questions/17134716/…
  • 请看下面的答案!
【解决方案2】:
  1. Python 代码返回 2005 年至 2014 年期间按年记录的最高气温和最低气温的折线图。每天的最高气温和最低气温之间的区域应加阴影。
  2. 叠加 2015 年数据的散点图,显示 2015 年打破十年记录(2005-2014 年)记录高点或记录低点的任何点(高点和低点)。
  3. 删除闰年日期(即 2 月 29 日)。

    from datetime import datetime
    import pandas as pd
    import matplotlib.pyplot as plt
    
    pd.set_option("display.max_rows",None,"display.max_columns",None)
    data = pd.read_csv('data/C2A2_data/BinnedCsvs_d400/fb441e62df2d58994928907a91895ec62c2c42e6cd075c2700843b89.csv') 
    newdata = data[(data['Date'] >= '2005-01-01') & (data['Date'] <= '2014-12-12')]
    datamax = newdata[newdata['Element']=='TMAX']
    datamin = newdata[newdata['Element']=='TMIN']
    datamax['Date'] = pd.to_datetime(datamax['Date'])
    datamin['Date'] = pd.to_datetime(datamin['Date'])
    datamax["day_of_year"] = datamax["Date"].dt.dayofyear
    datamax = datamax.groupby('day_of_year').max()
    datamin["day_of_year"] = datamin["Date"].dt.dayofyear
    datamin = datamin.groupby('day_of_year').min()
    datamax = datamax.reset_index()
    datamin = datamin.reset_index()
    datamin['Date'] = datamin['Date'].dt.strftime('%Y-%m-%d')
    datamax['Date'] = datamax['Date'].dt.strftime('%Y-%m-%d')
    datamax = datamax[~datamax['Date'].str.contains("02-29")]
    datamin = datamin[~datamin['Date'].str.contains("02-29")]
    
    breakoutdata = data[(data['Date']  > '2014-12-31')]
    datamax2015 = breakoutdata[breakoutdata['Element']=='TMAX']
    datamin2015 = breakoutdata[breakoutdata['Element']=='TMIN']
    datamax2015['Date'] = pd.to_datetime(datamax2015['Date'])
    datamin2015['Date'] = pd.to_datetime(datamin2015['Date'])
    datamax2015["day_of_year"] = datamax2015["Date"].dt.dayofyear
    datamax2015 = datamax2015.groupby('day_of_year').max()
    datamin2015["day_of_year"] = datamin2015["Date"].dt.dayofyear
    datamin2015 = datamin2015.groupby('day_of_year').min()
    datamax2015 = datamax2015.reset_index()
    datamin2015 = datamin2015.reset_index()
    datamin2015['Date'] = datamin2015['Date'].dt.strftime('%Y-%m-%d')
    datamax2015['Date'] = datamax2015['Date'].dt.strftime('%Y-%m-%d')
    datamax2015 = datamax2015[~datamax2015['Date'].str.contains("02-29")]
    datamin2015 = datamin2015[~datamin2015['Date'].str.contains("02-29")]
    
    dataminappend = datamin2015.join(datamin,on="day_of_year",rsuffix="_new")
    lower = dataminappend.loc[dataminappend["Data_Value_new"]>dataminappend["Data_Value"]]
    datamaxappend = datamax2015.join(datamax,on="day_of_year",rsuffix="_new")
    upper = datamaxappend.loc[datamaxappend["Data_Value_new"]<datamaxappend["Data_Value"]]
    
    upper['Date'] = pd.to_datetime(upper['Date']) 
    lower['Date'] = pd.to_datetime(lower['Date']) 
    datamax['Date'] = pd.to_datetime(datamax['Date']) 
    datamin['Date'] = pd.to_datetime(datamin['Date']) 
    
    ax = plt.gca()
    plt.plot(datamax['day_of_year'],datamax['Data_Value'],color='red')
    plt.plot(datamin['day_of_year'],datamin['Data_Value'], color='blue')
    plt.scatter(upper['day_of_year'],upper['Data_Value'],color='purple')
    plt.scatter(lower['day_of_year'],lower['Data_Value'], color='cyan')
    
    plt.ylabel("Temperature (degrees C)",color='navy')
    plt.xlabel("Date",color='navy',labelpad=15)
    plt.title('Record high and low temperatures by day (2005-2014)', alpha=1.0,color='brown',y=1.08)
    ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.35),fancybox=False,labels=['Record high','Record low'])
    plt.xticks(rotation=30)
    plt.fill_between(range(len(datamax['Date'])), datamax['Data_Value'], datamin['Data_Value'],color='yellow',alpha=0.8)
    plt.show()
    
  4. 我已使用 Datamin['Date'] = datamin['Date'].dt.strftime('%Y-%m-%d') 将“日期”列转换为字符串。

  5. 然后我使用 upper['Date'] = pd.to_datetime(upper['Date']) 将其转换回 'datetime' 格式

  6. 然后我使用“日期”作为 x 值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2020-07-24
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多