根据列值和其他列更新 Pandas 个单元格
Update Pandas Cells based on Column Values and Other Columns
我希望根据一列中的值更新许多列;这对于一个循环来说很容易,但是当有很多列和很多行时,我的应用程序花费的时间太长了。获得每个字母所需计数的最优雅方法是什么?
期望的输出:
Things count_A count_B count_C count_D
['A','B','C'] 1 1 1 0
['A','A','A'] 3 0 0 0
['B','A'] 1 1 0 0
['D','D'] 0 0 0 2
选项 1
apply
+ value_counts
s = pd.Series([list('ABC'), list('AAA'), list('BA'), list('DD')], name='Things')
pd.concat([s, s.apply(lambda x: pd.Series(x).value_counts()).fillna(0)], axis=1)
选项 2
使用 pd.DataFrame(s.tolist())
+ stack
/ groupby
/ unstack
pd.concat([s,
pd.DataFrame(s.tolist()).stack() \
.groupby(level=0).value_counts() \
.unstack(fill_value=0)],
axis=1)
最优雅的绝对是sklearn的CountVectorizer。
我会先告诉你它是如何工作的,然后我会在一行中完成所有的事情,所以你会看到它有多优雅。
首先,我们一步一步来:
让我们创建一些数据
raw = ['ABC', 'AAA', 'BA', 'DD']
things = [list(s) for s in raw]
然后读入一些包并初始化count vectorizer
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
cv = CountVectorizer(tokenizer=lambda doc: doc, lowercase=False)
接下来我们生成一个计数矩阵
matrix = cv.fit_transform(things)
names = ["count_"+n for n in cv.get_feature_names()]
并保存为数据框
df = pd.DataFrame(data=matrix.toarray(), columns=names, index=raw)
生成这样的数据框:
count_A count_B count_C count_D
ABC 1 1 1 0
AAA 3 0 0 0
BA 1 1 0 0
DD 0 0 0 2
优雅版:
以上所有内容都在一行中
df = pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)
时间:
您提到您正在处理一个相当大的数据集,所以我使用 %%timeit 函数来估算时间。
@piRSquared 之前的回复(否则看起来非常好!)
pd.concat([s, s.apply(lambda x: pd.Series(x).value_counts()).fillna(0)], axis=1)
100 loops, best of 3: 3.27 ms per loop
我的回答:
pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)
1000 loops, best of 3: 1.08 ms per loop
根据我的测试,CountVectorizer 大约快 3 倍。
我希望根据一列中的值更新许多列;这对于一个循环来说很容易,但是当有很多列和很多行时,我的应用程序花费的时间太长了。获得每个字母所需计数的最优雅方法是什么?
期望的输出:
Things count_A count_B count_C count_D
['A','B','C'] 1 1 1 0
['A','A','A'] 3 0 0 0
['B','A'] 1 1 0 0
['D','D'] 0 0 0 2
选项 1
apply
+ value_counts
s = pd.Series([list('ABC'), list('AAA'), list('BA'), list('DD')], name='Things')
pd.concat([s, s.apply(lambda x: pd.Series(x).value_counts()).fillna(0)], axis=1)
选项 2
使用 pd.DataFrame(s.tolist())
+ stack
/ groupby
/ unstack
pd.concat([s,
pd.DataFrame(s.tolist()).stack() \
.groupby(level=0).value_counts() \
.unstack(fill_value=0)],
axis=1)
最优雅的绝对是sklearn的CountVectorizer。
我会先告诉你它是如何工作的,然后我会在一行中完成所有的事情,所以你会看到它有多优雅。
首先,我们一步一步来:
让我们创建一些数据
raw = ['ABC', 'AAA', 'BA', 'DD']
things = [list(s) for s in raw]
然后读入一些包并初始化count vectorizer
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
cv = CountVectorizer(tokenizer=lambda doc: doc, lowercase=False)
接下来我们生成一个计数矩阵
matrix = cv.fit_transform(things)
names = ["count_"+n for n in cv.get_feature_names()]
并保存为数据框
df = pd.DataFrame(data=matrix.toarray(), columns=names, index=raw)
生成这样的数据框:
count_A count_B count_C count_D
ABC 1 1 1 0
AAA 3 0 0 0
BA 1 1 0 0
DD 0 0 0 2
优雅版:
以上所有内容都在一行中
df = pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)
时间:
您提到您正在处理一个相当大的数据集,所以我使用 %%timeit 函数来估算时间。
@piRSquared 之前的回复(否则看起来非常好!)
pd.concat([s, s.apply(lambda x: pd.Series(x).value_counts()).fillna(0)], axis=1)
100 loops, best of 3: 3.27 ms per loop
我的回答:
pd.DataFrame(data=cv.fit_transform(things).toarray(), columns=["count_"+n for n in cv.get_feature_names()], index=raw)
1000 loops, best of 3: 1.08 ms per loop
根据我的测试,CountVectorizer 大约快 3 倍。