pandas 每小时使用Python的客户数量[已关闭]

vwkv1x7d  于 2023-11-15  发布在  Python
关注(0)|答案(2)|浏览(79)

已关闭。此问题需要details or clarity。目前不接受回答。
**要改进此问题吗?**通过editing this post添加详细信息并阐明问题。

2天前关闭。
Improve this question
我的框架有两列REGIS_DAY和REGIS_HOUR。REGIS_DAY是一个月中的一天,REGIS_HOUR是一天中的小时

REGIS_DAY REGIS_HOUR  REGIS_DATE     REGIS_TIME
7             16       7/10/2011     16:21:05
3             3        3/10/2011     3:57:45
16            4        16/10/2011    4:08:47
24            3        24/10/2011    3:09:47
29            13       29/10/2011    13:43:40
7             16       7/10/2011     16:41:05
3             3        3/10/2011     3:24:45
3             3        3/10/2011     3:24:00
29            13       29/10/2011    13:43:01
29            13       29/10/2011    13:10:40
29            13       29/10/2011    13:20:40

字符串
我需要找出每小时的客户数量,所以我每天循环(即31),然后再循环24小时

`data_3124 = np.zeros((31,24), dtype = float)
for i in range(31):
    for j in range(24):
        number = (df.REGIS_DAY == (i+1)) & (df.REGIS_HOUR == j)
        data_3124[i,j] = number.sum()`


这里所有的值都是0
Aprat从上面的代码,我尝试了

isin funtion


和检查值
我明白我的解决方法是错误的
输出应

REGIS_DAY   REGIS_HOUR    sum
7             16           2
3             3            3
29            13           4
16            4            1
24            3            1


这意味着在日期7和16小时,客户总数为2,日期3和3小时的客户总数为3
分享我的原始数据供您参考

REGIS_DATE  REGIS_TIME  REGIS_DAY REGIS_HOUR 
1/10/2011    0:00:11    1          0 
1/10/2011    0:05:11    1          0 
1/10/2011    0:05:18    1          0 
1/10/2011    0:06:34    1          0  
1/10/2011    0:06:54    1          0 
1/10/2011    0:10:20    1          0 
1/10/2011    0:12:21    1          0 
1/10/2011    0:12:45    1          0 
1/10/2011    0:13:48    1          0 
1/10/2011    0:14:40    1          0 
1/10/2011    0:14:42    1          0 
1/10/2011    0:16:25    1          0 
1/10/2011    0:35:21    1          0 
1/10/2011    0:37:58    1          0 
1/10/2011    0:38:37    1          0 
1/10/2011    0:43:03    1          0 
1/10/2011    0:47:10    1          0 
1/10/2011    0:48:56    1          0 
1/10/2011    0:53:43    1          0


REGIS_DATE REGIS_TIME为原始数据,代码如下:

dates = df['REGIS_DATE'].str.split(pat = '/', n = 2, expand = True)
    time = df['REGIS_TIME'].str.split(pat = ':', n = 1, expand = True)

    date = dates[0]
    year = dates[2]
    df["REGIS_DAY"] = date
    df["REGIS_HOUR"] =time[0]
    df["REGIS_YEAR"] = year


更新列REGIS_DAY REGIS_HOUR以进行处理
我只过滤2011年使用下面的代码

filt_year = df['REGIS_YEAR'] == '2011'
    df_2011 = df.loc[filt_year].copy()

  • OCa的 * 和 *Kirill Kondratenko的 * 解决方案,不带out循环
df_result = (df_2011
      .groupby(['REGIS_DAY', 'REGIS_HOUR'])
      .size()
      .reset_index()
      .rename(columns={0:'sum'}))

and 
df1 = df_2011.groupby(by=['REGIS_DAY','REGIS_HOUR'], as_index=False).size()


结果低于预期/正确

REGIS_DAY REGIS_HOUR  sum
0          1          0   19
1          1          1   20
2          1         10   35
3          1         11   45
4          1         12   42
5          1         13   47
6          1         14   31
7          1         15   43
8          1         16   38
9          1         17   28
10         1         18   17
11         1         19   32
12         1          2   14
13         1         20   44
14         1         21   45
15         1         22   28
16         1         23   30
17         1          3    9
18         1          4   11
19         1          5    7
20         1          6   10
21         1          7   13
22         1          8   27
23         1          9   25


只使用循环是不给预期的结果.结果的总和是0

*df_2011.to_dict() 输出如下 *

...},
 'REGIS_DAY': {54452: '7',
  28303: '3',
  121169: '16',
  146488: '24',
  23665: '29',
  12883: '11',
  139438: '4',
  
   ...},
 'REGIS_HOUR': {54452: '16',
  28303: '3',
  121169: '4',
  146488: '3',
  23665: '13',
  12883: '6',
  139438: '13',
 



**df_2011.dtypes**
  • 输出如下 *
Hospital_Name     object
REGIS_DATE        object
REGIS_TIME        object
reg_sec            int64
Triage Time       object
triage_sec         int64
Triage_Class      object
Age              float64
Gender            object
Race              object
REGIS_DAY         object
REGIS_HOUR        object
REGIS_YEAR        object
dtype: object
iezvtpos

iezvtpos1#

1.正确设置数据类型

您正在将数值方法应用于仅包含字符串的数据。这就是为什么您的尝试返回空表。num1将不匹配字符串'1'。虽然有些方法不关心数据类型(请参阅下面的groupby方法),但numpy数组上的嵌套循环确实需要实际数字。因此,您必须从以下数据类型转换开始:

df[['REGIS_DAY','REGIS_HOUR']] = df[['REGIS_DAY','REGIS_HOUR']].astype('int')

df.dtypes

REGIS_DAY      int32
REGIS_HOUR     int32
REGIS_DATE    object
REGIS_TIME    object
dtype: object

字符串
现在你可以工作了。
有关此主题的更多信息,请参见例如Change column type in pandas

2.关于第一次尝试

您的代码段编写正确,并返回预期的31*24数组。它看起来不像是收集数据的最方便方法,以便您可以进一步使用它们。

# This was fine all along:
data_3124 = np.zeros((31,24), dtype = float)
for i in range(31):
    for j in range(24):
        number = (df.REGIS_DAY == (i+1)) & (df.REGIS_HOUR == j)
        data_3124[i,j] = number.sum()


你可以用几个检查来探测它:

data_3124.sum()
11
# This is indeed the number of rows in the initial dataframe

data_3124[6,16]
2.0
# Number of hits for day 7, hour 16.

3. Python的方法

现在只需一行groupby来定义另一个你需要的字符串:(不需要从字符串到整数的转换)

df1 = df.groupby(by=['REGIS_DAY','REGIS_HOUR'], as_index=False).size()

   REGIS_DAY  REGIS_HOUR  size
0          3           3     3
1          7          16     2
2         16           4     1
3         24           3     1
4         29          13     4


如果你仍然想用循环来解决这个问题,我们也可以研究一下,但要知道这是推荐的方法。
欲进一步阅读,您可以尝试:Pandas sum by groupby, but exclude certain columns

4.嵌套循环的建议

接下来是一个解决方案,它可能更好地与您当前的赋值保持一致。它也会产生您想要的输出。同样,这个解决方案需要事先进行字符串到整数的转换,如答案的第一部分所述。
这里的原则是以单行结构的形式填充每个命中(客户存在的小时数)的列表,然后将所有命中重新组合到一个最终的结构中(不太关心代码效率)。

df_list = []

for i in range(31):
    for j in range(24):
        # view dataframe subset meeting condition
        df_ij = df.loc[(df['REGIS_DAY']==i+1) & (df['REGIS_HOUR']==j)]
        # its number of rows
        s_ij = len(df_ij)
        # assign it to table
        if s_ij>0:
            df_list.append(pd.DataFrame({'REGIS_DAY'  : [i],
                                         'REGIS_HOUR' : [j],
                                         'sum'        : [s_ij]}))
# Concatenate the list of dataframes into a single table.
pd.concat(df_list, axis=0)

   REGIS_DAY  REGIS_HOUR  sum
0          2           3    3
0          6          16    2
0         15           4    1
0         23           3    1
0         28          13    4


对于进一步的阅读,我推荐Creating an empty Pandas DataFrame, and then filling it

  • 作为良好的实践,只需避免像pandas函数那样命名列。这里即sum,因为语法df.sum可能无法提供您所期望的内容。请将列'Sum'改为列'Sum'足以消除歧义。*
nr7wwzry

nr7wwzry2#

看起来你需要:

df = (df
      .groupby(['REGIS_DAY', 'REGIS_HOUR'])
      .size()
      .reset_index()
      .rename(columns={0:'sum'}))

print(df)

字符串
输出量:

REGIS_DAY    REGIS_HOUR  sum
0   3                3      3
1   7               16      2
2   16               4      1
3   24               3      1
4   29              13      4


如果你仍然想使用循环,用途:

REGIS_DAY = []
REGIS_HOUR = []
sum = []
for i in range(31):
    for j in range(24):
        REGIS_DAY.append(i)
        REGIS_HOUR.append(j)
        sum.append(len(df[(df['REGIS_DAY'] == i) & (df['REGIS_HOUR'] == j)]))
        
df_new = pd.DataFrame({'REGIS_DAY': REGIS_DAY,
                       'REGIS_HOUR': REGIS_HOUR,
                       'sum': sum})

相关问题