unique函数(先记下来)

来源http://www.cnblogs.com/heyonggang/archive/2013/08/07/3243477.html

 一.unique函数

类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素

该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序改变了),表示无重复的值范围得结束。


// sort words alphabetically so we can find the duplicates 
sort(words.begin(), words.end()); 
     /* eliminate duplicate words: 
      * unique reorders words so that each word appears once in the 
      *    front portion of words and returns an iterator one past the 
unique range; 
      * erase uses a vector operation to remove the nonunique elements 
      */ 
 vector<string>::iterator end_unique =  unique(words.begin(), words.end()); 
 words.erase(end_unique, words.end());

在STL中unique函数是一个去重函数, unique的功能是去除相邻的重复元素(只保留一个),其实它并不真正把重复的元素删除,是把重复的元素移到后面去了,然后依然保存到了原数组中,然后 返回去重后最后一个元素的地址,因为unique去除的是相邻的重复元素,所以一般用之前都会要排一下序。

若调用sort后,vector的对象的元素按次序排列如下:

sort  jumps  over quick  red  red  slow  the  the turtle

则调用unique后,vector中存储的内容是:

 

 

 

 

 

 

注意,words的大小并没有改变,依然保存着10个元素;只是这些元素的顺序改变了。调用unique“删除”了相邻的重复值。给“删除”加上引号是因为unique实际上并没有删除任何元素,而是将无重复的元素复制到序列的前段,从而覆盖相邻的重复元素。unique返回的迭代器指向超出无重复的元素范围末端的下一个位置。

注意:算法不直接修改容器的大小。如果需要添加或删除元素,则必须使用容器操作。

example:

#include <iostream>
#include <cassert>
#include <algorithm>
#include <vector>
#include <string>
#include <iterator>
 using namespace std;

 int main()
{
    //cout<<"Illustrating the generic unique algorithm."<<endl;
    const int N=11;
    int array1[N]={1,2,0,3,3,0,7,7,7,0,8};
    vector<int> vector1;
    for (int i=0;i<N;++i)
        vector1.push_back(array1[i]);

    vector<int>::iterator new_end;
    new_end=unique(vector1.begin(),vector1.end());    //"删除"相邻的重复元素
    assert(vector1.size()==N);

    vector1.erase(new_end,vector1.end());  //删除(真正的删除)重复的元素
    copy(vector1.begin(),vector1.end(),ostream_iterator<int>(cout," "));
    cout<<endl;

    return 0;
}

运行结果为:

 

二、unique_copy函数

算法标准库定义了一个名为unique_copy的函数,其操作类似于unique。

唯一的区别在于:前者接受第三个迭代器实参,用于指定复制不重复元素的目标序列。

unique_copy根据字面意思就是去除重复元素再执行copy运算。

编写程序使用unique_copy将一个list对象中不重复的元素赋值到一个空的vector对象中。

//使用unique_copy算法
//将一个list对象中不重复的元素赋值到一个空的vector对象中
#include<iostream>
#include<list>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
    int ia[7] = {5 , 2 , 2 , 2 , 100 , 5 , 2};
    list<int> ilst(ia , ia + 7);
    vector<int> ivec;

    //将list对象ilst中不重复的元素复制到空的vector对象ivec中
    //sort(ilst.begin() , ilst.end());  //不能用此种排序,会报错
    ilst.sort();  //在进行复制之前要先排序,切记
    unique_copy(ilst.begin() , ilst.end() , back_inserter(ivec));

    //输出vector容器
    cout<<"vector: "<<endl;
    for(vector<int>::iterator iter = ivec.begin() ; iter != ivec.end() ; ++iter)
        cout<<*iter<<" ";
    cout<<endl;

    return 0;
}

假如

list<int> ilst(ia , ia + 7);
改为:vector<int> ilst(ia , ia + 7);

则排序时可用:

sort(ilst.begin() , ilst.end());

 这里要注意list和vector的排序用什么方法。

《Effective STL》里这些话可能有用处:
item 31
  
  “我们总结一下你的排序选择:
   ● 如果你需要在vector、string、deque或数组上进行完全排序,你可以使用sort或stable_sort。
   ● 如果你有一个vector、string、deque或数组,你只需要排序前n个元素,应该用partial_sort
   ● 如果你有一个vector、string、deque或数组,你需要鉴别出第n个元素或你需要鉴别出最前的n个元素,而不用知道它们的顺序,nth_element是你应该注意和调用的。
   ● 如果你需要把标准序列容器的元素或数组分隔为满足和不满足某个标准,你大概就要找partition或stable_partition。
   ● 如果你的数据是在list中,你可以直接使用partition和stable_partition,你可以使用list的sort来代替sort和stable_sort。如果你需要partial_sort或nth_element提供的效果,你就必须间接完成这个任务,但正如我在上面勾画的,会有很多选择。
  
  另外,你可以通过把数据放在标准关联容器中的方法以保持在任何时候东西都有序。你也可能会考虑标准非STL容器priority_queue,它也可以总是保持它的元素有序。





### 回答1: 当然,下面是使用Python编写一个计算PSI的函数的示例代码: ```python import numpy as np def calculate_psi(expected, actual, buckettype='bins', buckets=10, axis=0): ''' 计算预期和实际值之间的PSI。 Parameters: expected (array-like): 预期值。 actual (array-like): 实际值。 buckettype (str): 桶类型,“bins”(相同数量的桶)或“quantiles”(相同数量的记录)。 buckets (int): 桶数量(仅适用于“bins”类型)。 axis (int): 计算PSI的轴。 Returns: psi (float): 预期和实际值之间的PSI值。 ''' def psi(expected_array, actual_array, buckets): '''计算单个桶的PSI''' if len(expected_array) == 0 or len(actual_array) == 0: return 0 expected_prop = np.sum(expected_array) / np.sum(expected_array + actual_array) actual_prop = np.sum(actual_array) / np.sum(expected_array + actual_array) if actual_prop == 0: actual_prop = 0.001 if expected_prop == 0: expected_prop = 0.001 return (expected_prop - actual_prop) * np.log(expected_prop / actual_prop) # 创建桶 if buckettype == 'bins': breakpoints = np.arange(0, buckets + 1) / buckets * 100 expected_buckets = np.percentile(expected, breakpoints) actual_buckets = np.percentile(actual, breakpoints) elif buckettype == 'quantiles': expected_buckets = np.unique(np.percentile(expected, np.arange(0, 101, 100 / buckets))) actual_buckets = np.unique(np.percentile(actual, np.arange(0, 101, 100 / buckets))) else: raise ValueError('buckettype must be "bins" or "quantiles"') # 计算每个桶的PSI expected_hist = np.histogram(expected, expected_buckets)[0] actual_hist = np.histogram(actual, actual_buckets)[0] psi_values = [psi(expected_hist[i:i + 1], actual_hist[i:i + 1], buckets) for i in range(len(expected_hist))] # 返回总PSI return np.sum(psi_values) ``` 这个函数使用numpy库来处理数组和数据的统计方法。它使用了内部函数`psi`来计算每个桶的PSI,该函数基于参考和实际分布中的记录计算每个桶的psi。最后,该函数使用np.sum函数将所有PSI值相加,并返回总PSI。 ### 回答2: PSI(Preventive Services Index)是一种评估预防性保健服务利用率的指标,可以衡量人们对预防性保健服务的需求程度和利用率。下面是一个用def函数编写的计算PSI的Python代码: ```python def calculate_PSI(current_rate, historical_rate): """ 计算PSI的函数 参数: current_rate (float): 当前时间段的服务利用率 historical_rate (float): 历史时间段的服务利用率 返回值: PSI (float): PSI指数 """ # 计算当前时间段和历史时间段的占比 current_ratio = current_rate / (current_rate + 1e-10) historical_ratio = historical_rate / (historical_rate + 1e-10) # 计算当前时间段和历史时间段的自然对数 current_ln = math.log(current_ratio) historical_ln = math.log(historical_ratio) # 计算PSI指数 PSI = (current_ratio - historical_ratio) * (current_ln - historical_ln) return PSI # 使用示例 current_rate = 0.75 historical_rate = 0.60 PSI = calculate_PSI(current_rate, historical_rate) print("PSI指数为:", PSI) ``` 其中,函数`calculate_PSI`接受当前时间段的服务利用率`current_rate`和历史时间段的服务利用率`historical_rate`作为输入参数,并返回计算得到的PSI指数。在函数中,通过计算当前时间段和历史时间段的占比,并利用自然对数计算PSI指数。最后,我们可以通过调用该函数,并传入具体的服务利用率值来计算PSI指数,并将结果打印出来。 ### 回答3: 以下是用def函数写的求PSI的Python代码: ```python def calculate_PSI(actual, expected): # 将actual和expected转换为numpy数组 import numpy as np actual = np.array(actual) expected = np.array(expected) # 计算实际和预期的占比 actual_ratio = actual / np.sum(actual) expected_ratio = expected / np.sum(expected) # 计算每个区间的PSI psi = np.sum((expected_ratio - actual_ratio) * np.log(expected_ratio / actual_ratio)) return psi # 示例: actual_values = [10, 20, 30, 40, 50] # 实际值 expected_values = [15, 25, 35, 45, 55] # 预期值 psi_value = calculate_PSI(actual_values, expected_values) print("PSI值为:", psi_value) ``` 以上代码定义了一个名为`calculate_PSI`的函数,该函数接受两个参数`actual`和`expected`,分别表示实际值和预期值。函数将实际值和预期值转换为numpy数组,然后计算实际和预期的占比。接下来,通过计算每个区间的PSI值,使用公式Σ((E-A) * ln(E/A)),最后返回PSI值。 在示例中,我们将实际值和预期值传递给`calculate_PSI`函数,然后打印出计算得到的PSI值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值