首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Pandas重采样中包含字符串

如何在Pandas重采样中包含字符串
EN

Stack Overflow用户
提问于 2015-01-16 22:44:14
回答 3查看 6.8K关注 0票数 2

我有一个数据序列,其中一个随机日期列作为我的索引,一个带编号的值,以及三列,每列都表示是否激活了安全机制来阻止带编号的值。示例如下:

代码语言:javascript
运行
复制
DateTime         Safe1    Safe2    Safe3    Measurement

1/8/2013 6:06     N       Y        N    

1/8/2013 6:23     N       Y        N    

1/8/2013 6:40     N       N        N        28

1/8/2013 6:57     N        N       N        31

我需要使用Pandas重新采样数据,以便创建干净的半小时间隔数据,取存在的值的平均值。当然,这会删除三个安全字符串列。

但是,我想包含一个列,指示在整个半小时间隔内是否激活了安全机制的任何组合。

如何获得在重采样数据中显示Y的字符串列,表明在三个安全机制列中的原始数据中存在Y,但在测量中没有任何值?

基于以上内容的期望输出:

代码语言:javascript
运行
复制
DateTime      Safe1  Measurement

1/8/2013 6:00 Y      

1/8/2013 6:30 N      29.5
EN

回答 3

Stack Overflow用户

发布于 2015-01-18 14:57:52

我不认为使用resample函数可以做你想做的事情,因为你不能做太多的定制。我们必须使用groupby操作来执行TimeGrouper。

首先创建数据:

代码语言:javascript
运行
复制
import pandas as pd

index = ['1/8/2013 6:06', '1/8/2013 6:23', '1/8/2013 6:40', '1/8/2013 6:57']

data = {'Safe1' : ['N', 'N', 'N', 'N'], 
        'Safe2': ['Y', 'Y', 'N', 'N'], 
        'Safe3': ['N', 'N', 'N', 'N'], 
        'Measurement': [0,0,28,31]}

df = pd.DataFrame(index=index, data=data)
df.index = pd.to_datetime(df.index)
df

输出:

代码语言:javascript
运行
复制
Measurement Safe1 Safe2 Safe3
2013-01-08 06:06:00            0     N     Y     N
2013-01-08 06:23:00            0     N     Y     N
2013-01-08 06:40:00           28     N     N     N
2013-01-08 06:57:00           31     N     N     N

然后,让我们添加一个帮助器列,名为安全,这将是所有Safex列的串联。如果至少有一个是在Safe列中,我们将知道安全机制已被激活。

代码语言:javascript
运行
复制
df['Safe'] = df['Safe1'] + df['Safe2'] + df['Safe3']
print df

输出:

代码语言:javascript
运行
复制
Measurement Safe1 Safe2 Safe3 Safe
2013-01-08 06:06:00            0     N     Y     N  NYN
2013-01-08 06:23:00            0     N     Y     N  NYN
2013-01-08 06:40:00           28     N     N     N  NNN
2013-01-08 06:57:00           31     N     N     N  NNN

最后,我们将定义一个自定义函数,它将返回是如果至少有一个是在作为参数传递的字符串列表中。

该自定义函数在安全列,在我们按30分钟间隔对其进行分组后:

代码语言:javascript
运行
复制
def func(x):
    x = ''.join(x.values)
    return 'Y' if 'Y' in x else 'N'

df.groupby(pd.TimeGrouper(freq='30Min')).agg({'Measurement': 'mean', 'Safe': func })

输出:

代码语言:javascript
运行
复制
Safe  Measurement
2013-01-08 06:00:00    Y          0.0
2013-01-08 06:30:00    N         29.5
票数 3
EN

Stack Overflow用户

发布于 2017-03-24 23:26:54

这是一个使用pandas内置重采样函数的答案。

首先将3个组合在一起安全值添加到单个列中:

代码语言:js
复制
df['Safe'] = df.Safe1 + df.Safe2 + df.Safe3

将3个字母的字符串转换为0-1变量:

代码语言:js
复制
df.Safe = df.Safe.apply(lambda x: 1 if 'Y' in x else 0)

为'Safes‘列编写一个自定义的重采样函数:

代码语言:javascript
运行
复制
def f(x):
  if sum(x) > 0: return 'Y'
  else: return 'N'

最后,重新采样:

代码语言:js
复制
df.resample('30T').Safe.agg({'Safe': f}).join(df.resample('30T').Measurement.mean())

输出:

代码语言:javascript
运行
复制
Safe  Measurement 
2013-01-08 06:00:00  Y        0.0
2013-01-08 06:30:00  N        29.5
票数 2
EN

Stack Overflow用户

发布于 2019-06-20 14:14:47

我手动重新采样日期(如果是四舍五入,则很容易)....

下面是一个例子

代码语言:javascript
运行
复制
from random import shuffle
from datetime import datetime, timedelta
from itertools import zip_longest
from random import randint, randrange, seed
from tabulate import tabulate
import pandas as pd

def df_to_md(df):
    print(tabulate(df, tablefmt="pipe",headers="keys"))

seed(42)

people=['tom','dick','harry']
avg_score=[90,50,10]
date_times=[n for n in pd.date_range(datetime.now()-timedelta(days=2),datetime.now(),freq='5 min').values]
scale=1+int(len(date_times)/len(people))
score =[randint(i,100)*i/10000 for i in avg_score*scale]

df=pd.DataFrame.from_records(list(zip(date_times,people*scale,score)),columns=['When','Who','Status'])
# Create 3 records tom should score 90%, dick 50% and poor harry only 10% 
# Tom should score well
df_to_md(df[df.Who=='tom'].head())

表格是Markdown格式的-只是为了方便我的剪切和粘贴...

代码语言:javascript
运行
复制
|    | When                       | Who   |   Status |
|---:|:---------------------------|:------|---------:|
|  0 | 2019-06-18 14:07:17.457124 | tom   |    0.9   |
|  3 | 2019-06-18 14:22:17.457124 | tom   |    0.846 |
|  6 | 2019-06-18 14:37:17.457124 | tom   |    0.828 |
|  9 | 2019-06-18 14:52:17.457124 | tom   |    0.9   |
| 12 | 2019-06-18 15:07:17.457124 | tom   |    0.819 |

哈里得分很低

代码语言:js
复制
df_to_md(df[df.Who=='harry'].head())
代码语言:javascript
运行
复制
|    | When                       | Who   |   Status |
|---:|:---------------------------|:------|---------:|
|  2 | 2019-06-18 14:17:17.457124 | harry |    0.013 |
|  5 | 2019-06-18 14:32:17.457124 | harry |    0.038 |
|  8 | 2019-06-18 14:47:17.457124 | harry |    0.023 |
| 11 | 2019-06-18 15:02:17.457124 | harry |    0.079 |
| 14 | 2019-06-18 15:17:17.457124 | harry |    0.064 |

让我们得到每个人每小时的平均值

代码语言:javascript
运行
复制
def round_to_hour(t):
    # Rounds to nearest hour by adding a timedelta hour if minute >= 30
    return (t.replace(second=0, microsecond=0, minute=0, hour=t.hour)
               +timedelta(hours=t.minute//30))

并使用此方法生成新列。

代码语言:javascript
运行
复制
df['WhenRounded']=df.When.apply(lambda x: round_to_hour(x))
df_to_md(df[df.Who=='tom'].head())

这应该是tom的数据-显示原始的和四舍五入的数据。

代码语言:javascript
运行
复制
|    | When                       | Who   |   Status | WhenRounded         |
|---:|:---------------------------|:------|---------:|:--------------------|
|  0 | 2019-06-18 14:07:17.457124 | tom   |    0.9   | 2019-06-18 14:00:00 |
|  3 | 2019-06-18 14:22:17.457124 | tom   |    0.846 | 2019-06-18 14:00:00 |
|  6 | 2019-06-18 14:37:17.457124 | tom   |    0.828 | 2019-06-18 15:00:00 |
|  9 | 2019-06-18 14:52:17.457124 | tom   |    0.9   | 2019-06-18 15:00:00 |
| 12 | 2019-06-18 15:07:17.457124 | tom   |    0.819 | 2019-06-18 15:00:00 |

我们可以重新采样..。通过分组和使用分组函数

按四舍五入的日期和Person (Datetime和Str)对象分组)-在本例中,我们希望均值价值,但也有其他可用的。

代码语言:javascript
运行
复制
df_resampled=df.groupby(by=['WhenRounded','Who'], axis=0).agg({'Status':'mean'}).reset_index()
# Output in Markdown format
df_to_md(df_resampled[df_resampled.Who=='tom'].head())
代码语言:javascript
运行
复制
|    | WhenRounded         | Who   |   Status |
|---:|:--------------------|:------|---------:|
|  2 | 2019-06-18 14:00:00 | tom   |  0.873   |
|  5 | 2019-06-18 15:00:00 | tom   |  0.83925 |
|  8 | 2019-06-18 16:00:00 | tom   |  0.86175 |
| 11 | 2019-06-18 17:00:00 | tom   |  0.84375 |
| 14 | 2019-06-18 18:00:00 | tom   |  0.8505  |

让我们检查一下tom @ 14:00的平均值

代码语言:js
复制
print("Check tom 14:00 .86850  ... {:6.5f}".format((.900+.846+.828+.900)/4))
代码语言:js
复制
Check tom 14:00 .86850  ... 0.86850

希望这能对你有所帮助

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27986447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档