Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何检查一个数组中存在于另一个数组中的值的百分比?_Python_Arrays_Pandas - Fatal编程技术网

Python 如何检查一个数组中存在于另一个数组中的值的百分比?

Python 如何检查一个数组中存在于另一个数组中的值的百分比?,python,arrays,pandas,Python,Arrays,Pandas,我在pandas中有一个数据帧,如下所示: app_id_x period app_id_y 10 [pb6uhl15, xn66n2cr, e68t39yp, s7xun0k1, wab2z... 2015-19 NaN 11 [uscm6kkb, tja4ma8u, qcwhw33w, ux5bbkjz, mmt3s... 2015-20 NaN 12 [txdbauhy, dib24pab, xt69u57g, n9e6a6ol, d9f7m... 201

我在pandas中有一个数据帧,如下所示:

    app_id_x    period  app_id_y
10  [pb6uhl15, xn66n2cr, e68t39yp, s7xun0k1, wab2z...   2015-19 NaN
11  [uscm6kkb, tja4ma8u, qcwhw33w, ux5bbkjz, mmt3s...   2015-20 NaN
12  [txdbauhy, dib24pab, xt69u57g, n9e6a6ol, d9f7m...   2015-21 NaN
13  [21c2b5ca5e7066141b2e2aea35d7253b3b8cce11, oht...   2015-22 [g8m4lecv, uyhsx6lo, u9ue1zzo, kw06m3f5, wvqhq...
14  [64lbiaw3, jum7l6yd, a5d00f6aba8f1505ff22bc1fb...   2015-23 [608a223c57e1174fc64775dd2fd8cda387cc4a47, ze4...
15  [gcg8nc8k, jkrelo7v, g9wqigbc, n806bjdu, piqgv...   2015-24 [kz8udlea, zwqo7j8w, 6d02c9d74b662369dc6c53ccc...
16  [uc311krx, wpd7gm75, am8p0spd, q64dcnlm, idosz...   2015-25 [fgs0qhtf, awkcmpns, e0iraf3a, oht91x5j, mv4uo...
17  [wilhuu0x, b51xiu51, ezt7goqr, qj6w7jh6, pkzkv...   2015-26 [zwqo7j8w, dzdfiof5, phwoy1ea, e7hfx7mu, 40fdd...
18  [xn43bho3, uwtjxy6u, ed65xcuj, ejbgjh61, hbvzt...   2015-27 [ze4rr0vi, kw06m3f5, be532399ca86c053fb0a69d13...
我想做的是,对于每一个
时段
,这是一行,检查
app\u id\u y
值列表中的
app\u id\u x
值的百分比,例如,如果ze4rr0vi和gm83klja在
app\u id\u x
内,该行中包含53个值,然后应该有一个名为
adoption\u rate
的新列,它是:

period   adoption_rate
2015-9      0%
2015-22     3.56%
2015-25     4.56%
2015-26     5.10%
2015-35     4.58%
2015-36     1.23%
这个怎么样:

df[adoption_rate] = [100.*len(set(df.loc[i,app_id_x]) &\ 
                     set(df.loc[i,app_id_y]))/len(set(df.loc[i,app_id_x]))\   
                     if type(df.loc[i,app_id_x])==list and \ 
                     type(df.loc[i,app_id_x])==list \
                     else 0. for i in df.index]
编辑:修复了任何数组中存在重复值的情况。

如何:

df[adoption_rate] = [100.*len(set(df.loc[i,app_id_x]) &\ 
                     set(df.loc[i,app_id_y]))/len(set(df.loc[i,app_id_x]))\   
                     if type(df.loc[i,app_id_x])==list and \ 
                     type(df.loc[i,app_id_x])==list \
                     else 0. for i in df.index]
编辑:修复了任何数组中存在重复值的情况。

您可以使用它来获取两个数组之间的公共元素,这完成了需要完成的大部分工作。为了获得输出,我将编写一个函数来获取给定行的重叠百分比,然后使用
apply
添加一个采用率列

def get_overlap_pcnt(row):
    # Get the overlap between arrays.
    overlap = len(np.intersect1d(row['app_id_x'], row['app_id_y']))

    # Compute the percent common.
    if overlap == 0:
        pcnt = 0
    else:
        pcnt = 100*overlap/len(row['app_id_y'])

    return '{:.2f}%'.format(pcnt)

df['adoption_rate'] = df.apply(get_overlap_pcnt, axis=1)
从你的问题中,我不太清楚你是想要
app\u id\u y
还是
app\u id\u x
作为分母,但这是一个很容易做出的改变。下面是使用我创建的一些示例数据的示例输出

                app_id_x         app_id_y   period adoption_rate
0  [a, b, c, d, e, f, g]              NaN  2015-08         0.00%
1              [b, c, d]     [b, c, d, e]  2015-09        75.00%
2     [a, b, c, x, y, z]        [x, y, z]  2015-10       100.00%
3     [q, w, e, r, t, y]  [a, b, c, d, e]  2015-11        20.00%
4              [x, y, z]        [a, b, x]  2015-12        33.33%
您可以使用获取两个数组之间的公共元素,这完成了需要完成的大部分工作。为了获得输出,我将编写一个函数来获取给定行的重叠百分比,然后使用
apply
添加一个采用率列

def get_overlap_pcnt(row):
    # Get the overlap between arrays.
    overlap = len(np.intersect1d(row['app_id_x'], row['app_id_y']))

    # Compute the percent common.
    if overlap == 0:
        pcnt = 0
    else:
        pcnt = 100*overlap/len(row['app_id_y'])

    return '{:.2f}%'.format(pcnt)

df['adoption_rate'] = df.apply(get_overlap_pcnt, axis=1)
从你的问题中,我不太清楚你是想要
app\u id\u y
还是
app\u id\u x
作为分母,但这是一个很容易做出的改变。下面是使用我创建的一些示例数据的示例输出

                app_id_x         app_id_y   period adoption_rate
0  [a, b, c, d, e, f, g]              NaN  2015-08         0.00%
1              [b, c, d]     [b, c, d, e]  2015-09        75.00%
2     [a, b, c, x, y, z]        [x, y, z]  2015-10       100.00%
3     [q, w, e, r, t, y]  [a, b, c, d, e]  2015-11        20.00%
4              [x, y, z]        [a, b, x]  2015-12        33.33%

其他答案缺少的是,这是一种非常不自然的数据存储方式。通常,数据帧中的值应该是标量

为了解决此问题,表示数据的更好方法是将它们重新格式化为两个数据帧,即X和Y。在X中,行是句点,列是ID(例如“g8m4lecv”)。如果值在该期间的X列中,则X数据框中的条目为
1
,对于Y也是如此

这使得执行您想要执行的操作更加容易

下面是:

import pandas as pd
import numpy as np


# from the comment by @jezrael . Super useful, thanks
df = pd.DataFrame({'app_id_x': {10: ['pb6uhl15', 'pb6uhl15', 'pb6uhl15'], 11: ['pb6uhl15', 'pb6uhl15', 'e68t39yp', 's7xun0k1'], 12: [ 'pb6uhl15', 's7xun0k1'], 13: [ 's7xun0k1'], 14: ['pb6uhl15', 'pb6uhl15', 'e68t39yp', 's7xun0k1']}, 'app_id_y': {10: ['pb6uhl15'], 11: ['pb6uhl15'], 12: np.nan, 13: ['pb6uhl15', 'xn66n2cr', 'e68t39yp', 's7xun0k1'], 14: ['e68t39yp', 'xn66n2cr']}, 'period': {10: '2015-19', 11: '2015-20', 12: '2015-21', 13: '2015-22', 14: '2015-23'}})


# pulling the data out of the lists in the starting dataframe
new_data = []
for _,row in df.iterrows():
    for col in ['app_id_x','app_id_y']:
        vals = row[col]
        if isinstance(vals,list):
            for v in set(vals):
                new_data.append((row['period'],col[-1],v,1))

new_df = pd.DataFrame(new_data, columns = ['period','which_app','val','exists'])

# splitting the data into two frames
def get_one_group(app_id):
    return new_df.groupby('which_app').get_group(app_id).drop('which_app', axis=1)

X = get_one_group('x')
Y = get_one_group('y')


# converting to the desired format
def convert_to_indicator_matrix(df):
    return df.set_index(['period','val']).unstack('val').fillna(0)

X = convert_to_indicator_matrix(X)
Y = convert_to_indicator_matrix(Y)
现在,真正解决你的问题非常容易。我不清楚您到底需要解决什么问题,但假设您想知道,对于每个时段,
number\u id\u in\u两者
除以
number\u id\u in\u Y

combined = (X * Y).fillna(0)
combined.sum(axis=1) / Y.sum(axis=1)

其他答案缺少的是,这是一种非常不自然的数据存储方式。通常,数据帧中的值应该是标量

为了解决此问题,表示数据的更好方法是将它们重新格式化为两个数据帧,即X和Y。在X中,行是句点,列是ID(例如“g8m4lecv”)。如果值在该期间的X列中,则X数据框中的条目为
1
,对于Y也是如此

这使得执行您想要执行的操作更加容易

下面是:

import pandas as pd
import numpy as np


# from the comment by @jezrael . Super useful, thanks
df = pd.DataFrame({'app_id_x': {10: ['pb6uhl15', 'pb6uhl15', 'pb6uhl15'], 11: ['pb6uhl15', 'pb6uhl15', 'e68t39yp', 's7xun0k1'], 12: [ 'pb6uhl15', 's7xun0k1'], 13: [ 's7xun0k1'], 14: ['pb6uhl15', 'pb6uhl15', 'e68t39yp', 's7xun0k1']}, 'app_id_y': {10: ['pb6uhl15'], 11: ['pb6uhl15'], 12: np.nan, 13: ['pb6uhl15', 'xn66n2cr', 'e68t39yp', 's7xun0k1'], 14: ['e68t39yp', 'xn66n2cr']}, 'period': {10: '2015-19', 11: '2015-20', 12: '2015-21', 13: '2015-22', 14: '2015-23'}})


# pulling the data out of the lists in the starting dataframe
new_data = []
for _,row in df.iterrows():
    for col in ['app_id_x','app_id_y']:
        vals = row[col]
        if isinstance(vals,list):
            for v in set(vals):
                new_data.append((row['period'],col[-1],v,1))

new_df = pd.DataFrame(new_data, columns = ['period','which_app','val','exists'])

# splitting the data into two frames
def get_one_group(app_id):
    return new_df.groupby('which_app').get_group(app_id).drop('which_app', axis=1)

X = get_one_group('x')
Y = get_one_group('y')


# converting to the desired format
def convert_to_indicator_matrix(df):
    return df.set_index(['period','val']).unstack('val').fillna(0)

X = convert_to_indicator_matrix(X)
Y = convert_to_indicator_matrix(Y)
现在,真正解决你的问题非常容易。我不清楚您到底需要解决什么问题,但假设您想知道,对于每个时段,
number\u id\u in\u两者
除以
number\u id\u in\u Y

combined = (X * Y).fillna(0)
combined.sum(axis=1) / Y.sum(axis=1)

我认为您可以使用更好的样本并添加所需的样本输出。也许有助于打印pd.数据框({'app_id_x':{10:['pb6uhl15','pb6uhl15','pb6uhl15','pb6uhl15','pb6uhl15','e68t39yp','s7xun0k1',12:['pb6uhl15','s7xun0k1',13:['s7xun0k1',14:['pb6uhl15','pb6uhl15','e68t9yp','s7xun1k1','s7xun1k1','app id:'s7xunkuhl15','11'][pb6uhl15',xn66n2cr',e68t39yp',s7xun0k1',14:[e68t39yp',xn66n2cr']},句号:{10:'2015-19',11:'2015-20',12:'2015-21',13:'2015-22',14:'2015-23'}请随意修改它以获得更好的结果。祝你好运。我认为你可以使用更好的样本并添加所需的样本输出。也许有帮助-
打印pd.DataFrame({'AppID\uX':{10:11:[pb6uhl15,”pb6uhl15,”pb6uhl15,”pb6uhl15,”pb6uhl15,”pb6uhl15,”pb6uhl15,“E666T39YP,”S7XN111111'[pb6uhl15”,“pb6uhl15”,“PB6UH6UHL15”,“PB6UL15,”PB6UH6UL15,”PB6UL15,”pb6uhl15,”PB6UL15,”PB6UL15,”E6UL15,”E6UL15,”E6UL15,”E6UL15,”E6UL15,”E6UL15,”E6UL15,”E66UL15,”E66UL15,”E6UL15,”E6UL15,”E66UL15,”E6666UL15,”E6L15,”E66666L15,”E6L15,”E],14:[e68t39yp',xn66n2cr'],期间:{10:'2015-19',11:'2015-20',12:'2015-21',13:'2015-22',14:'2015-23'})
请随意修改它以获得更好的结果。祝你好运。我喜欢这个解决方案。使用
np.intersect1d
而不是
set
有什么好处吗?我没有计时,但我怀疑
np.intersect1d
对于大型数据集有更好的性能,因为它使用了numpy的底层C/C++/Fortran代码。我喜欢这个解决方案。是使用
np.intersect1d
而不是
set
是一个优势吗?我没有计时,但我怀疑
np.intersect1d
对于大型数据集有更好的性能,因为它使用了numpy的底层C/C++/Fortran代码。