下面是我的数据帧的一个小样本,它有25000多行长:
In [58]: df
Out[58]:
Send_Agent Send_Amount
0 ADR000264 361.940000
1 ADR000264 12.930000
2 ADR000264 11.630000
3 ADR000264 12.930000
4 ADR000264 64.630000
5 ADR000264 12.930000
6 ADR000264 77.560000
7 ADR000264 145.010000
8 API185805 112.34
9 API185805 56.45
10 API185805 48.97
11 API185805 85.44
12 API185805 94.33
13 API185805 116.45
有2个发送代理ADR000264和API185805。我试着把本福德的法律测试应用到发送金额上。我可以成功地做到这一点,当我尝试所有的发送金额,而不考虑发送代理。下面是我提取前导数字的函数。在
^{pr2}$此函数应用于Send_Amount列时,可以正常工作:
In [75]: df['Send_Amount'].apply(leading_digit)
Out[75]:
0 3
1 1
2 1
3 1
4 6
5 1
6 7
7 1
8 1
它给出一个序列输出,并从Send_Amount列中提取前导数字。在
但当我在按Send_Agent分组后尝试相同的函数时,我得到了错误的结果:
In [74]: df['Send_Amount'].groupby(df['Send_Agent']).apply(leading_digit)
Out[74]:
Send_Agent
ADR000264 0
API185805 6
dtype: int64
与…相同groupby.agg组在
In [59]: grouped = df.groupby('Send_Agent')
In [60]: a = grouped.agg({'Send_Amount':leading_digit})
In [61]: a
Out[61]:
Send_Amount
Send_Agent
ADR000264 0
API185805 6
编辑:
现在我们有了前导数字的计数。在
In [16]: result = df.assign(Leading_Digit = df['Send_Amount'].astype(str).str[0]).groupby('Send_Agent')['Leading_Digit'].value_counts(sort=False)
In [17]: result
Out[17]:
Send_Agent Leading_Digit
ADR000264 1 5509
2 4748
3 2090
4 2497
5 979
6 1206
7 529
8 549
9 729
API185805 1 1707
2 1966
3 744
4 1218
5 306
6 605
7 138
8 621
9 76
数据类型:int64
In [18]: type(result)
Out[18]: pandas.core.series.Series
我不需要画图表。我只需要从benford值中减去计数。在
In [22]: result = result.to_frame()
In [29]: result.columns = ['Count']
In [32]: result
Out[32]:
Count
Send_Agent Leading_Digit
ADR000264 1 5509
2 4748
3 2090
4 2497
5 979
6 1206
7 529
8 549
9 729
API185805 1 1707
2 1966
3 744
4 1218
5 306
6 605
7 138
8 621
9 76
In [33]: result['Count'] = (result['Count'])/(result['Count'].sum())
In [34]: result
Out[34]:
Count
Send_Agent Leading_Digit
ADR000264 1 0.210131
2 0.181104
3 0.079719
4 0.095244
5 0.037342
6 0.046001
7 0.020178
8 0.020941
9 0.027806
API185805 1 0.065110
2 0.074990
3 0.028379
4 0.046458
5 0.011672
6 0.023077
7 0.005264
8 0.023687
9 0.002899
In [35]: result.unstack()
Out[35]:
Count \
Leading_Digit 1 2 3 4 5 6
Send_Agent
ADR000264 0.210131 0.181104 0.079719 0.095244 0.037342 0.046001
API185805 0.065110 0.074990 0.028379 0.046458 0.011672 0.023077
Leading_Digit 7 8 9
Send_Agent
ADR000264 0.020178 0.020941 0.027806
API185805 0.005264 0.023687 0.002899
So , benford values for 1 to 9 as follows
d = 0.30103, 0.176091, 0.124939, 0.09691, 0.0791812, 0.0669468, 0.0579919, 0.0511525, 0.0457575
我要做的就是从结果中减去它们。在
我对熊猫和Python还很陌生。那么,我该怎么做呢。在
很酷的项目。我将使用随机生成的数据集进行说明:
看起来像这样:
^{pr2}$现在,如果将该函数应用于序列
Send_Amount
,它将返回另一个带前导数字的序列。如果首先对它们进行分组,则需要为每个分组指定所需的结果类型。该函数不是为获取一个组并返回该组的结果而设计的。它只返回一个数字的前导数字。在相反,为了验证Benford's law,您需要检查前导数字的频率分布。因为您已经为前导数字创建了一个列,现在可以通过Send_Agent进行分组并对该列调用
value_counts
。总而言之,它是这样的:您也可以使用
df.groupby('Send_Agent')['Leading_Digit'].value_counts(sort=False)
完成此操作(在创建列之后)。我只是一步到位。最终,分布将(希望)如下所示:要找出理论概率和观测频率之间的差异,可以执行以下操作:
请注意,我传递了
normalize=True
以便它计算比例而不是频率。在现在,您可以用以下方法进行区别:
在这里,unstack将Send_代理程序带到列。
np.log10(1+(1/np.arange(1, 10)))
计算理论概率。您也可以传递先前定义的阵列。由于我们要逐行减去元素,因此subtract
方法有axis=0
参数。最后,.abs()
取结果的绝对值。在您可以将^{} 与^{} 一起使用,因为}聚合输出:
agg
或{如果数字大于
^{pr2}$9
,请使用str[:2]
:Transformation。在
相关问题 更多 >
编程相关推荐