我有一个包含"name"列的数据集US Baby Names.尽管这样做没有多大意义,但我正在努力寻找该专栏中的中位数名称. 也就是说,将名字按升序排列后,根据名字的频率,将有一个"中间值",这就是我想要找到的,而不必对整个列(Pandas Series)进行实际排序,然后找到中间最大的名字.因此,我需要一种简单的内置方法来查找中间名称.

~*~

编辑[协调世界时(UTC)5:51 ]:名称的中位数应基于名称的字母/词典顺序. 此外,下面是CSV文件的一部分(第一行是标题):

,Id,Name,Year,Gender,State,Count
11349,11350,Emma,2004,F,AK,62
11350,11351,Madison,2004,F,AK,48
11351,11352,Hannah,2004,F,AK,46
11352,11353,Grace,2004,F,AK,44
11353,11354,Emily,2004,F,AK,41
11354,11355,Abigail,2004,F,AK,37

~*~

我try 了内置的PANDA Medium()方法,但它对非数字值并不真正有效,尽管将numeric_only属性设置为False:

import pandas as pd
baby_names = pd.read_csv(
    "Pandas_DataMart\\DataMart\\06_Stats\\US_Baby_Names\\US Baby Names.xlsx")

print(baby_names['Name'].median(numeric_only=False))

在Midate()方法的内部工作过程中,有一系列错误行,但最终我得到的结果是:

TypeError: could not convert string to float: 'Emma'

因此,似乎不适用于非数字值.还是我做错了什么?

以下是完整的错误消息以供参考:

Traceback (most recent call last):
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\nanops.py", line 720, in nanmedian
values = values.astype("f8")
ValueError: could not convert string to float: 'Emma'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "c:\Users\...\BabyNames.py", line 18, in <module>
print(baby_names['Name'].median(numeric_only=False))
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\generic.py", line 10802, in median
return NDFrame.median(self, axis, skipna, level, numeric_only, **kwargs)
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\generic.py", line 10374, in median
return self._stat_function(
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\generic.py", line 10354, in _stat_function
return self._reduce(
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\series.py", line 4392, in _reduce
return op(delegate, skipna=skipna, **kwds)
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\nanops.py", line 156, in f
result = alt(values, axis=axis, skipna=skipna, **kwds)
File "C:\Users\JohnDoe\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\nanops.py", line 723, in nanmedian
raise TypeError(str(err)) from err
TypeError: could not convert string to float: 'Emma'

推荐答案

original answer: median by count

假设您需要具有计数中值的名称,请使用自定义函数.用value_counts计算频率,然后得到中间值:

df = pd.DataFrame({'names': ['A', 'B', 'C', 'A', 'C', 'C']})

def count_median(s):
    c = s.value_counts()
    return c.index[len(c)//2]

out = df['names'].agg(count_median)

输出:'A'

alternative: median by lexicographic order

如果您想要按词典顺序排序的名称的中位数/中间值,则必须排序:

df['names'].sort_values().iloc[len(df)//2]

输出:'C'

或者,如果您想要数据长度为偶数的第一个值:

df['names'].sort_values().iloc[(len(df)-1)//2]

输出:'B'

您只需使用numpy.partition对一半的数据进行排序,就可以显著提高工作效率:

mid = (len(df)-1)//2
out = np.partition(df['names'], mid)[mid]

Python相关问答推荐

如何清理无用的Python包?

七段显示不完整

如何在句子之间添加空白但忽略链接?

Django关于UniqueBindition的更新

删除pandas rame时间序列列中未更改的值

由于瓶颈,Python代码执行太慢-寻求性能优化

在matplotlib动画gif中更改配色方案

在for循环中仅执行一次此操作

拆分pandas列并创建包含这些拆分值计数的新列

计算相同形状的两个张量的SSE损失

如何在Python中使用io.BytesIO写入现有缓冲区?

TARete错误:类型对象任务没有属性模型'

当多个值具有相同模式时返回空

Pandas 有条件轮班操作

查找两极rame中组之间的所有差异

用Python解密Java加密文件

如何列举Pandigital Prime Set

"使用odbc_connect(raw)连接字符串登录失败;可用于pyodbc"

我对我应该做什么以及我如何做感到困惑'

我的字符串搜索算法的平均时间复杂度和最坏时间复杂度是多少?