我在多列中包含以下数据:
col1 col2 col3
123456 ['mary','ralph', ''bob'] ['bob','sam']
456789 ['george','fred', susie'] ['ralph','mary', 'bob']
789123 ['mary', bob'] ['bob']
我最终在每一列上都需要一个value_counts。为了使所有东西都脱离清单,我正在尝试爆炸。我可以将值爆炸后放入其列中,没问题。但是,那些了解explode的人知道我的value_counts会被夸大,因为将其应用于多个列时,explode会重复导致值重复
爆炸产生了这个例子,
col1 col2 col3
123456 mary bob
123456 mary sam
123456 mary george
123456 ralph bob
123456 ralph sam
123456 ralph george...etc.
很显然,这会引发我需要的每列准确的value_counts。 我试过在每个列上循环爆炸,然后在每个列爆炸后匹配第一列和爆炸列并删除重复项,这是行不通的。一直不喜欢自己不是房间里最聪明的人(有更多的知识要学习),所以我向您提出了这个问题的熊猫大师。 (看看我在那里做了什么?)。谢谢。
预期的输出,以便我可以对除col1之外的所有列进行value_counts:
123456 mary bob
123456 ralph sam
123456 bob george
456789 george ralph
456789 fred mary
456789 susie bob
789123 mary bob
789123 bob george
答案 0 :(得分:3)
IIUC,您可以#include <iostream>
#include <string>
#include <set>
using namespace std;
class Room {
private:
long id;
float level;
string name;
set<Room> connectedRooms= {};
public:
Room(long &id, float &level, set<Room> &connectedRooms) {
this->id = id;
this->level = level;
this->connectedRooms = connectedRooms;
}
Room() = default;
};
而不是循环爆炸:
apply
对于不规则列表:
print (df.set_index("col1").apply(pd.Series.explode))
col2 col3
col1
123456 mary bob
123456 ralph sam
123456 bob george
456789 george ralph
456789 fred mary
456789 susie bob
789123 mary bob
789123 bob george
或者:
s = df.set_index("col1").agg("sum").to_frame().explode(0)
print (s.groupby(level=0)[0].apply(pd.Series.value_counts))
col2 mary 2
bob 2
george 1
susie 1
ralph 1
john 1
fred 1
col3 bob 3
george 2
sam 1
ralph 1
mary 1
Name: 0, dtype: int64
答案 1 :(得分:3)
我要列表中元素的 value_counts ,首先需要展平该列,然后使用 value_counts 例如:
import pandas as pd
from itertools import chain
df = pd.DataFrame(data=[
[123456, ['mary', 'ralph', 'bob'], ['bob', 'sam', 'george']],
[456789, ['george', 'fred', 'susie'], ['ralph', 'mary', 'bob']],
[789123, ['mary', 'bob'], ['bob', 'george']]
], columns=['col1', 'col2', 'col3'])
print(pd.Series(chain.from_iterable(df['col2'])).value_counts())
输出
mary 2
bob 2
susie 1
george 1
fred 1
ralph 1
dtype: int64
上面的结果是示例col2
的 value_counts 。
答案 2 :(得分:1)
您可以尝试:
df.melt('col1').explode('value')\ #melt col2 and col3 into one column and explode
.groupby(['variable','value'])\ #Groupby melted columns
.count()['col1']\ #count
.unstack(0, fill_value=0) #reshape to show counts per col2 and col3 by name
输出:
variable col2 col3
value
bob 2 3
fred 1 0
george 1 0
mary 2 1
ralph 1 1
sam 0 1
susie 1 0
答案 3 :(得分:0)
我们可以使用stack
展开每个列表,然后使用cumcount
创建代理索引
# if not real lists you'll need `literal_eval
from ast import literal_eval
s = df.set_index('col1').stack().map(literal_eval).explode().to_frame()
df1 = s.set_index(s.groupby(level=[0,1]).cumcount(),append=True).unstack(1).droplevel(0,1)
print(df1)
col2 col3
col1
123456 0 mary bob
1 ralph sam
2 bob george
456789 0 george ralph
1 fred mary
2 susie bob
789123 0 mary bob
1 bob george
答案 4 :(得分:0)
您可以应用一个函数,该函数接受flatten
的每一列并返回该列的value_counts
。然后将NaN
的值替换为0,并将返回的帧强制转换为整数以整理输出:
import pandas as pd
from pandas.core.common import flatten
def nested_valuecounts(series):
flattened = list(flatten(series))
return pd.Series.value_counts(flattened)
out = df[["col2", "col3"]].apply(nested_valuecounts).fillna(0).astype(int)
print(out)
col2 col3
bob 1 3
fred 1 0
george 1 2
mary 2 1
ralph 1 1
sam 0 1
susie 1 0
答案 5 :(得分:-1)
您可以在爆炸前合并各列
df['col4']=df['col2']+df['col3']
df.drop(columns = ['col2','col3'],inplace = True)
然后在'col4'
上爆炸