如何使用Pandas Python获取数据框中每列的最大长度

34

我有一个数据框,其中大多数列都是varchar/object类型。列的长度差异很大,可以在3-1000+的范围内任意变化。现在,对于每一列,我想测量最大长度。

我知道如何计算列的最大长度。如果它是varchar,则:

max(df.char_col.apply(len))

如果它是数字(float8或int64),那么:

max(df.num_col.map(str).apply(len))

但是我的数据框有数百列,我想同时计算所有列的最大长度。问题在于,这些列有不同的数据类型,我不知道如何一次性处理它们。

因此,问题1:如何获取数据框中每个列的最大列长度

现在我正在尝试仅针对varchar/object类型列使用以下代码进行计算:

xx = df.select_dtypes(include = ['object'])
for col in [xx.columns.values]:
   maxlength = [max(xx.col.apply(len))]

我只选择了对象类型的列并尝试编写for循环。但它不起作用。可能在for循环中使用apply()不是一个好主意。

问题2:如何仅获取每个对象类型列的最大长度

样本数据框:

d1 = {'name': ['john', 'tom', 'bob', 'rock', 'jimy'], 'DoB': ['01/02/2010', '01/02/2012', '11/22/2014', '11/22/2014', '09/25/2016'], 'Address': ['NY', 'NJ', 'PA', 'NY', 'CA'], 'comment1': ['Very good performance', 'N/A', 'Need to work hard', 'No Comment', 'Not satisfactory'], 'comment2': ['good', 'Meets Expectation', 'N', 'N/A', 'Incompetence']}
df1 = pd.DataFrame(data = d1)
df1['month'] = pd.DatetimeIndex(df1['DoB']).month
df1['year'] = pd.DatetimeIndex(df1['DoB']).year
7个回答

39

在使用 str 和 len 方法后,您可以使用 min max。

df["A"].str.len().max()
df["A"].str.len().min()

df["Column Name"].str.len().max()
df["Column Name"].str.len().min()

有趣的是,最简单、最干净的答案只有一个赞,而不是24个。无论如何,这个答案对我来说完美地解决了问题。 - Dan Nissenbaum
感谢你,丹。非常感谢 :) - Mohamad A Sallal
简洁而清晰! - undefined

38

一种解决方案是使用numpy.vectorize。这可能比基于pandas的解决方案更有效。

您可以使用pd.DataFrame.select_dtypes来选择object列。

import pandas as pd
import numpy as np

df = pd.DataFrame({'A': ['abc', 'de', 'abcd'],
                   'B': ['a', 'abcde', 'abc'],
                   'C': [1, 2.5, 1.5]})

measurer = np.vectorize(len)

所有列的最大长度

res1 = measurer(df.values.astype(str)).max(axis=0)

array([4, 5, 3])

对象列的最大长度

res2 = measurer(df.select_dtypes(include=[object]).values.astype(str)).max(axis=0)

array([4, 5])
或者,如果您需要以字典形式输出:
res1 = dict(zip(df, measurer(df.values.astype(str)).max(axis=0)))

{'A': 4, 'B': 5, 'C': 3}

df_object = df.select_dtypes(include=[object])
res2 = dict(zip(df_object, measurer(df_object.values.astype(str)).max(axis=0)))

{'A': 4, 'B': 5}

3
不适用于大型数据集。出现警告numpy.core._exceptions.MemoryError: Unable to allocate 4.18 TiB for an array with shape (4130207, 5) and data type <U55682,意味着无法为形状为(4130207,5)且数据类型为<U55682的数组分配4.18 TiB的内存空间。 - Bouncner
1
@Harvey 发布了一个非常有效的答案:for column in df: print(column,"->", df[column].astype(str).str.len().max()) - Corina Roca

16

找到数据框中所有列(任何类型)的最大字符数:

for column in df:
    print(column,"->", df[column].astype(str).str.len().max())

它运行相当快,我正在一个有8000万行的数据框上使用它。


11

这里有一些很棒的回答,我也想贡献我的:

解决方案

dict([(v, df[v].apply(lambda r: len(str(r)) if r!=None else 0).max())for v in df.columns.values])

解释:

#convert tuple to dictionary
dict( 
    [
        #create a tuple such that (column name, max length of values in column)
        (v, df[v].apply(lambda r: len(str(r)) if r!=None else 0).max()) 
            for v in df.columns.values #iterates over all column values
    ])

样例输出

{'name': 4, 'DoB': 10, 'Address': 2, 'comment1': 21, 'comment2': 17}

10
只选择对象类型的列。
df2 = df1[[x for x in df1 if df1[x].dtype == 'object']]

获取每列的最大长度

max_length_in_each_col = df2.applymap(lambda x: len(x)).max()

由于某种原因,df2语句正在提取所有列类型,而不仅仅是对象。 - Steve Gon
我已将'O'更改为'object' - 现在应该选择对象列。 - Hrvoje
一旦选择了正确的列,xx.applymap(len).max() 就是我正在寻找的!我猜 xx.str.len().max() 也是同样的效果。 - Michel de Ruiter

4

我尝试了numpy.vectorize,但对于巨大的数据框,它给出了'内存错误'

以下代码完美地适用于我。它将为您提供电子表格中每一列的最大长度列表(使用pandas读入数据框):

import pandas as pd

xl = pd.ExcelFile('sample.xlsx')
df = xl.parse('Sheet1')

maxColumnLenghts = []
for col in range(len(df.columns)):
    maxColumnLenghts.append(max(df.iloc[:,col].astype(str).apply(len)))
print('Max Column Lengths ', maxColumnLenghts)

1
下面的两个答案都使用了dict推导式:
问题1:如何获取数据帧中每列的最大列长度。
max_length_all_cols = {col: df.loc[:, col].astype(str).apply(len).max() for col in df.columns}

问题2:如何获取仅针对对象类型列的每个列的最大长度
max_length_object_cols = {col: df.loc[:, col].astype(str).apply(len).max() for col in df.select_dtypes([object]).columns}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接