【问题标题】:Creating a loop program to apply values to pandas df创建一个循环程序以将值应用于 pandas df
【发布时间】:2020-06-25 19:02:28
【问题描述】:

这个问题可能是超级基本的,并为此道歉..

但我正在尝试创建一个 for 循环,该循环将根据条件将值 1 或 0 输入到 pandas 数据帧中。

import pandas as pd

def checkHour6(time):
    val = 0
    if  time == 6:
        val = 1 
    return val

def checkHour7(time):
    val = 0
    if  time == 7:
        val = 1 
    return val

def checkHour8(time):
    val = 0
    if  time == 8:
        val = 1 
    return val

def checkHour9(time):
    val = 0
    if  time == 9:
        val = 1 
    return val

def checkHour10(time):
    val = 0
    if  time == 10:
        val = 1 
    return val

我正在尝试的这个 for 循环将从 0 计数到 23,并且我正在尝试在循环过程中构建 pandas 数据框,该数据框将适当地输入 1 或 0 的值,但我缺少一些基本的东西作为最终的 df结果是一个空数据框。

创建空的df:

df = pd.DataFrame({'hour_6':[], 'hour_7':[], 'hour_8':[], 'hour_9':[], 'hour_10':[]})

For循环:

hour = -1

for i in range(24):
    stuff = []
    hour = hour + 1
    stuff.append(checkHour6(hour))
    stuff.append(checkHour7(hour))
    stuff.append(checkHour8(hour))
    stuff.append(checkHour9(hour))
    stuff.append(checkHour10(hour))
    df.append(stuff)

【问题讨论】:

  • 尽量不要对 pandas 使用循环,pandas 有办法做到这一点
  • 为什么使用 0/1 而不是正确的布尔值?
  • 我正在尝试创建一个用于机器学习过程的数据框。但也许布尔值也可以工作??

标签: python pandas


【解决方案1】:

快速浏览一下我要说的空白问题:

hour = -1
stuff = []

for i in range(24):    
    hour = hour + 1
    stuff.append(checkHour6(hour))
    stuff.append(checkHour7(hour))
    stuff.append(checkHour8(hour))
    stuff.append(checkHour9(hour))
    stuff.append(checkHour10(hour))

df.append(stuff)

可能是整个过程的更好解决方案。

【讨论】:

  • 感谢您的帮助,但这似乎创建了 120 行的数据框,我希望 df 有 24 行(代表一天 24 小时),其中列可能是 1 或 0,具体取决于hour的值
【解决方案2】:

我建议如下:

  • 仅使用一个带参数的 checkHour() 函数,
  • 根据pandas.DataFrame.append()documentationother参数必须是DataFrame或者Series/dict-like对象,或者这些的列表,所以不能使用list ,
  • 如果您想通过将新行附加到现有行来创建数据框,则必须对其进行分配。

代码可能如下所示:

def checkHour(time, hour):
    val = 0
    if time == hour:
        val = 1 
    return val

df = pd.DataFrame({'hour_6':[], 'hour_7':[], 'hour_8':[], 'hour_9':[], 'hour_10':[]})

hour = -1

for i in range(24):
    stuff = {}
    hour = hour + 1
    stuff['hour_6'] = checkHour(hour, 6)
    stuff['hour_7'] = checkHour(hour, 7)
    stuff['hour_8'] = checkHour(hour, 8)
    stuff['hour_9'] = checkHour(hour, 9)
    stuff['hour_10'] = checkHour(hour, 10)
    df = df.append(stuff, ignore_index=True)

结果如下:

>>> print(df)
    hour_6  hour_7  hour_8  hour_9  hour_10
0      0.0     0.0     0.0     0.0      0.0
1      0.0     0.0     0.0     0.0      0.0
2      0.0     0.0     0.0     0.0      0.0
3      0.0     0.0     0.0     0.0      0.0
4      0.0     0.0     0.0     0.0      0.0
5      0.0     0.0     0.0     0.0      0.0
6      1.0     0.0     0.0     0.0      0.0
7      0.0     1.0     0.0     0.0      0.0
8      0.0     0.0     1.0     0.0      0.0
9      0.0     0.0     0.0     1.0      0.0
10     0.0     0.0     0.0     0.0      1.0
11     0.0     0.0     0.0     0.0      0.0
12     0.0     0.0     0.0     0.0      0.0
13     0.0     0.0     0.0     0.0      0.0
14     0.0     0.0     0.0     0.0      0.0
15     0.0     0.0     0.0     0.0      0.0
16     0.0     0.0     0.0     0.0      0.0
17     0.0     0.0     0.0     0.0      0.0
18     0.0     0.0     0.0     0.0      0.0
19     0.0     0.0     0.0     0.0      0.0
20     0.0     0.0     0.0     0.0      0.0
21     0.0     0.0     0.0     0.0      0.0
22     0.0     0.0     0.0     0.0      0.0
23     0.0     0.0     0.0     0.0      0.0

编辑:

正如@Parfait 所说,在 for 循环中使用 pandas.DataFrame.append() 不好,因为它会导致二次复制。为避免这种情况,您可以制作一个字典列表(未来的数据框行),然后调用pd.DataFrame() 来制作一个数据框。代码如下所示:

def checkHour(time, hour):
    val = 0
    if time == hour:
        val = 1 
    return val

data = []
hour = -1

for i in range(24):
    stuff = {}
    hour = hour + 1
    stuff['hour_6'] = checkHour(hour, 6)
    stuff['hour_7'] = checkHour(hour, 7)
    stuff['hour_8'] = checkHour(hour, 8)
    stuff['hour_9'] = checkHour(hour, 9)
    stuff['hour_10'] = checkHour(hour, 10)
    data.append(stuff)

df = pd.DataFrame(data)

结果如下:

>>> print(df)
    hour_6  hour_7  hour_8  hour_9  hour_10
0        0       0       0       0        0
1        0       0       0       0        0
2        0       0       0       0        0
3        0       0       0       0        0
4        0       0       0       0        0
5        0       0       0       0        0
6        1       0       0       0        0
7        0       1       0       0        0
8        0       0       1       0        0
9        0       0       0       1        0
10       0       0       0       0        1
11       0       0       0       0        0
12       0       0       0       0        0
13       0       0       0       0        0
14       0       0       0       0        0
15       0       0       0       0        0
16       0       0       0       0        0
17       0       0       0       0        0
18       0       0       0       0        0
19       0       0       0       0        0
20       0       0       0       0        0
21       0       0       0       0        0
22       0       0       0       0        0
23       0       0       0       0        0

【讨论】:

【解决方案3】:

从数据列开始(现在几点) 然后可以从中查询所有其他比较。

import pandas as pd
df = pd.DataFrame(range(24), columns= ['data'])
for time in range(6,11):
   df[f'hour_{time}'] = df['data']%24==time

df = df.astype(int)

如果您愿意,您可以稍后删除数据列。

    data  hour_6  hour_7  hour_8  hour_9  hour_10
0      0       0       0       0       0        0
1      1       0       0       0       0        0
2      2       0       0       0       0        0
3      3       0       0       0       0        0
4      4       0       0       0       0        0
5      5       0       0       0       0        0
6      6       1       0       0       0        0
7      7       0       1       0       0        0
8      8       0       0       1       0        0
9      9       0       0       0       1        0
10    10       0       0       0       0        1
11    11       0       0       0       0        0
12    12       0       0       0       0        0
13    13       0       0       0       0        0
14    14       0       0       0       0        0
15    15       0       0       0       0        0
16    16       0       0       0       0        0
17    17       0       0       0       0        0
18    18       0       0       0       0        0
19    19       0       0       0       0        0
20    20       0       0       0       0        0
21    21       0       0       0       0        0
22    22       0       0       0       0        0
23    23       0       0       0       0        0

【讨论】:

    【解决方案4】:

    另一个非常简单的解决方案,如何创建数据框是使用pandas.get_dummies() 函数,如下所示:

    df = pd.DataFrame({'hour': range(24)})
    df = pd.get_dummies(df.hour, prefix='hour')
    df = df[['hour_6', 'hour_7', 'hour_8', 'hour_9', 'hour_10']]
    

    【讨论】:

    • 会在 0 小时开始吗?我想我需要从 0 到 23 的时间
    • @HenryHub,是的,它会的。函数range(23)将从0开始,以23结束。
    【解决方案5】:

    由于numpypandas 中的对象模型不同于一般的Python,请考虑避免在循环中构建对象,就像使用listdict 等更简单的可迭代对象一样。

    事实上,您的设置可以通过简单的DataFrame.pivot 处理,一列包含 24 个连续整数,无需任何函数或循环!事实上,您可以轻松返回更多小时列(即 hour_0-hour_24)或 reindex 为您需要的五列:

    数据

    df = (pd.DataFrame({'hour': ['hour' for _ in range(24)]})
            .assign(hour = lambda x: x['hour'] + '_' + pd.Series(range(24)).astype('str'),
                    num = 1)
         )
    
    df3.head(5)
    #      hour  num
    # 0  hour_0    1
    # 1  hour_1    1
    # 2  hour_2    1
    # 3  hour_3    1
    # 4  hour_4    1
    

    枢轴

    pvt_df = (df.pivot(columns='hour', values='num')
                .fillna(0)
                .reindex(['hour_6', 'hour_7', 'hour_8', 'hour_9', 'hour_10'], axis='columns')
             )
    
    pvt_df
    # hour  hour_6  hour_7  hour_8  hour_9  hour_10
    # 0        0.0     0.0     0.0     0.0      0.0
    # 1        0.0     0.0     0.0     0.0      0.0
    # 2        0.0     0.0     0.0     0.0      0.0
    # 3        0.0     0.0     0.0     0.0      0.0
    # 4        0.0     0.0     0.0     0.0      0.0
    # 5        0.0     0.0     0.0     0.0      0.0
    # 6        1.0     0.0     0.0     0.0      0.0
    # 7        0.0     1.0     0.0     0.0      0.0
    # 8        0.0     0.0     1.0     0.0      0.0
    # 9        0.0     0.0     0.0     1.0      0.0
    # 10       0.0     0.0     0.0     0.0      1.0
    # 11       0.0     0.0     0.0     0.0      0.0
    # 12       0.0     0.0     0.0     0.0      0.0
    # 13       0.0     0.0     0.0     0.0      0.0
    # 14       0.0     0.0     0.0     0.0      0.0
    # 15       0.0     0.0     0.0     0.0      0.0
    # 16       0.0     0.0     0.0     0.0      0.0
    # 17       0.0     0.0     0.0     0.0      0.0
    # 18       0.0     0.0     0.0     0.0      0.0
    # 19       0.0     0.0     0.0     0.0      0.0
    # 20       0.0     0.0     0.0     0.0      0.0
    # 21       0.0     0.0     0.0     0.0      0.0
    # 22       0.0     0.0     0.0     0.0      0.0
    # 23       0.0     0.0     0.0     0.0      0.0
    

    【讨论】:

    • @Parfait_ 你能帮我解决这个问题吗? stackoverflow.com/questions/60759277/…
    • 您对数据透视表解决方案的评论很有趣,但不承认此解决方案适合您!
    • 对不起,我还在学习!仍在研究数据透视表的工作原理/方式。我想我可以在使用 Microsoft Excel 时建立联系
    猜你喜欢
    • 1970-01-01
    • 2020-09-10
    • 2017-09-19
    • 2020-10-09
    • 2020-11-12
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    相关资源
    最近更新 更多