【问题标题】:Series [] and .loc[] sometimes returns a single value, and sometimes unexpectedly a single element Series containing the same valueSeries [] 和 .loc[] 有时会返回单个值,有时会意外返回包含相同值的单个元素 Series
【发布时间】:2022-01-24 07:50:07
【问题描述】:

在下面的代码中,我试图在 DataFrame 列中查找最长的字符串。

根据列的长度,下面的函数 (maxstr) 为短列返回单个值(如预期的那样),为长列返回单个元素系列(我没想到会这样)。

任何指针将不胜感激。

我使用了Find length of longest string in Pandas dataframe column中讨论的方法

import numpy as np
import pandas as pd

由于数据量很大,我会在数据帧和序列上显示信息。

从剪贴板读取数据帧

df = pd.read_clipboard(sep='\t', index_col=[0, 1, 2, 3, 4], na_values='')
print(f'{type(df)=}')
print(f'{df.shape=}')
print(f'{df.dtypes=}')
print(f'{df.columns=}')
type(df)=<class 'pandas.core.frame.DataFrame'>
df.shape=(581, 6)
df.dtypes=CID           int64
TITLE        object
FIRSTNAME    object
FUNCTION     object
PHONE        object
EMAIL        object
dtype: object
df.columns=Index(['CID', 'TITLE', 'FIRSTNAME', 'FUNCTION', 'PHONE', 'EMAIL'], dtype='object')

返回列/系列中等效的最大长度字符串的函数

def maxstr(ser: pd.Series):
    print(f'{type(ser)=}')

    print(f'\n{type(ser.astype(str).str.len().idxmax())=}')
    print(f'{type(ser[ser.astype(str).str.len().idxmax()])=}')

    # should return a single value and not a series
    return ser[ser.astype(str).str.len().idxmax()]

使用短列 (n=50),我得到一个 int(如预期的那样)

short = df.head(50)
short_return = maxstr(short['CID'])
type(ser)=<class 'pandas.core.series.Series'>

type(ser.astype(str).str.len().idxmax())=<class 'tuple'>
type(ser[ser.astype(str).str.len().idxmax()])=<class 'numpy.int64'>

使用来自相同数据帧(相同数据)(n=100)的长列,我得到一个系列(不是预期的??)

long = df.head(100)
long_return = maxstr(long['CID'])
type(ser)=<class 'pandas.core.series.Series'>
    
type(ser.astype(str).str.len().idxmax())=<class 'tuple'>
type(ser[ser.astype(str).str.len().idxmax()])=<class 'pandas.core.series.Series'>

在这两种情况下,我们都找到相同的 int 值(但一个在系列中,另一个作为单个值)

short_return == long_return.iloc[0]
True

int值是唯一的,所以在dataframe列中出现一次

value = short_return
print(f'The value: {value=}')
print(f'{sum(short["CID"] == value)=}')
print(f'{sum(long["CID"] == value)=}')
The value: value=1937
sum(short["CID"] == value)=1
sum(long["CID"] == value)=1

【问题讨论】:

  • 这个问题有 5 个屏幕,请将其减少到所需的绝对最少代码行数 minimal reproducible example。如果您有 5 个示例,理想情况下应该是 5 行。 (我们不需要任何打印、文档字符串或 cmets。)
  • 谢谢,我会尽量缩短它。

标签: python pandas dataframe series


【解决方案1】:

在我看来,问题是重复的索引值,所以如果 idxmax 返回重复的 tuple,则返回的不是标量,而是选择中的所有重复行。

避免它的简单解决方案是创建默认索引,这里更改:

df = pd.read_clipboard(sep='\t', index_col=[0, 1, 2, 3, 4], na_values='')

到:

df = pd.read_clipboard(sep='\t', na_values='')

没有MultiIndex,但默认RangeIndex

检查是否RangeIndex:

print (df.index)

如果需要MultiIndex 的解决方案是删除重复值:

df = pd.read_clipboard(sep='\t', index_col=[0, 1, 2, 3, 4], na_values='')
df = df[~df.index.duplicated()]

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2019-10-26
    • 2015-09-01
    • 2020-03-22
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    相关资源
    最近更新 更多