比较不同列的字符串长度数据框
Comparing a dataframe on string lengths for different columns
我正在尝试获取不同列的字符串长度。看起来很简单:
df['a'].str.len()
但我需要将它应用于多个列。然后得到最小值就可以了。
类似于:
df[['a','b','c']].str.len().min
我知道上面的方法行不通,但希望你明白了。 a
、b
、c
列都包含名称,我想检索最短的名称。
另外,由于数据量巨大,我避免创建其他列以节省大小。
我认为您需要列表理解,因为 string
函数仅适用于 Series
(column
):
print ([df[col].str.len().min() for col in ['a','b','c']])
apply
的另一个解决方案:
print ([df[col].apply(len).min() for col in ['a','b','c']])
样本:
df = pd.DataFrame({'a':['h','gg','yyy'],
'b':['st','dsws','sw'],
'c':['fffff','','rr'],
'd':[1,3,5]})
print (df)
a b c d
0 h st fffff 1
1 gg dsws 3
2 yyy sw rr 5
print ([df[col].str.len().min() for col in ['a','b','c']])
[1, 2, 0]
时间:
#[3000 rows x 4 columns]
df = pd.concat([df]*1000).reset_index(drop=True)
In [17]: %timeit ([df[col].apply(len).min() for col in ['a','b','c']])
100 loops, best of 3: 2.63 ms per loop
In [18]: %timeit ([df[col].str.len().min() for col in ['a','b','c']])
The slowest run took 4.12 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 2.88 ms per loop
结论:
apply
更快,但不适用于 None
.
df = pd.DataFrame({'a':['h','gg','yyy'],
'b':[None,'dsws','sw'],
'c':['fffff','','rr'],
'd':[1,3,5]})
print (df)
a b c d
0 h None fffff 1
1 gg dsws 3
2 yyy sw rr 5
print ([df[col].apply(len).min() for col in ['a','b','c']])
TypeError: object of type 'NoneType' has no len()
print ([df[col].str.len().min() for col in ['a','b','c']])
[1, 2.0, 0]
通过评论编辑:
#fail with None
print (df[['a','b','c']].applymap(len).min(axis=1))
0 1
1 0
2 2
dtype: int64
#working with None
print (df[['a','b','c']].apply(lambda x: x.str.len().min(), axis=1))
0 1
1 0
2 2
dtype: int64
我正在尝试获取不同列的字符串长度。看起来很简单:
df['a'].str.len()
但我需要将它应用于多个列。然后得到最小值就可以了。
类似于:
df[['a','b','c']].str.len().min
我知道上面的方法行不通,但希望你明白了。 a
、b
、c
列都包含名称,我想检索最短的名称。
另外,由于数据量巨大,我避免创建其他列以节省大小。
我认为您需要列表理解,因为 string
函数仅适用于 Series
(column
):
print ([df[col].str.len().min() for col in ['a','b','c']])
apply
的另一个解决方案:
print ([df[col].apply(len).min() for col in ['a','b','c']])
样本:
df = pd.DataFrame({'a':['h','gg','yyy'],
'b':['st','dsws','sw'],
'c':['fffff','','rr'],
'd':[1,3,5]})
print (df)
a b c d
0 h st fffff 1
1 gg dsws 3
2 yyy sw rr 5
print ([df[col].str.len().min() for col in ['a','b','c']])
[1, 2, 0]
时间:
#[3000 rows x 4 columns]
df = pd.concat([df]*1000).reset_index(drop=True)
In [17]: %timeit ([df[col].apply(len).min() for col in ['a','b','c']])
100 loops, best of 3: 2.63 ms per loop
In [18]: %timeit ([df[col].str.len().min() for col in ['a','b','c']])
The slowest run took 4.12 times longer than the fastest. This could mean that an intermediate result is being cached.
100 loops, best of 3: 2.88 ms per loop
结论:
apply
更快,但不适用于 None
.
df = pd.DataFrame({'a':['h','gg','yyy'],
'b':[None,'dsws','sw'],
'c':['fffff','','rr'],
'd':[1,3,5]})
print (df)
a b c d
0 h None fffff 1
1 gg dsws 3
2 yyy sw rr 5
print ([df[col].apply(len).min() for col in ['a','b','c']])
TypeError: object of type 'NoneType' has no len()
print ([df[col].str.len().min() for col in ['a','b','c']])
[1, 2.0, 0]
通过评论编辑:
#fail with None
print (df[['a','b','c']].applymap(len).min(axis=1))
0 1
1 0
2 2
dtype: int64
#working with None
print (df[['a','b','c']].apply(lambda x: x.str.len().min(), axis=1))
0 1
1 0
2 2
dtype: int64