Python 根据条件为自定义列指定值
这是我正在处理的数据集的一个示例() 我首先需要做的是,根据品牌、型号、第1-3列分别推出独特的型号,我是这样做的:Python 根据条件为自定义列指定值,python,pandas,pandas-groupby,transpose,Python,Pandas,Pandas Groupby,Transpose,这是我正在处理的数据集的一个示例() 我首先需要做的是,根据品牌、型号、第1-3列分别推出独特的型号,我是这样做的: import pandas as pd df = pd.read_csv("abhorrent.csv") noDupes = df[["brand", "model name", "column1", "column2", "column3"]].drop_duplicates().copy() 返回如下表: brand model column1 column2
import pandas as pd
df = pd.read_csv("abhorrent.csv")
noDupes = df[["brand", "model name", "column1", "column2", "column3"]].drop_duplicates().copy()
返回如下表:
brand model column1 column2 column3
Dell a aa bb
Dell a aa cc
Dell b aa bb
Dell b aa bb cc
Asus c aa cc bb
Asus c aa
Asus d aa cc bb
Asus d aa bb bb
但是,我需要基于类别、子类别和值创建列,并分配它们的值
列名称是category和sub-category的concats,我需要在其中输入这些对的值:
cat1_sc1
cat1_sc2
cat1_sc3
cat1_blank
cat2_sc1
cat2_blank
这些列不需要自动生成,我可以硬编码它们
问题是,我不知道如何基于非唯一数据帧填充这些列中的值
我期待的最终结果是:
brand model column1 column2 column3 cat1_sc1 cat1_sc2 cat1_sc3 cat1_blank cat2_sc1 cat2_blank
Dell a aa bb aaa bbb
Dell a aa cc ccc
Dell b aa bb ddd eee
Dell b aa bb cc fff
Asus c aa cc bb ggg hhh
Asus c aa iii
Asus d aa cc bb jjj
Asus d aa bb bb kkk lll
我能够在PostrgreSQL中完成这项工作,我的解决方案最初是在那里开发的,对每个预定义列使用一次更新。大致如下:
#fill the cat1_sc1 column
UPDATE transposed_table
SET cat1_sc1 = subquery.value
FROM
(SELECT ... FROM ... WHERE category = 'cat1' AND sub_category = 'sc1') subquery
WHERE brand = subquery.brand AND model = subquery.model etc
编辑:我的实际CSV有近500k行您可以执行以下操作:
noDupes['cat1_sc1'] = df[(df["category"] == "cat1") & (df["sub category"] == "sc1")]["value"]
你必须在所有类别和子类别上都这样做,但我想你明白了
编辑:
完整代码以使其全部运行:
import pandas as pd
df = pd.read_csv("abhorrent.csv")
cats = df["category"].drop_duplicates().tolist()
sub_cats = df["sub category"].drop_duplicates().tolist()
cat_sc_s = []
for cat in cats:
for sc in sub_cats:
name = str(cat) + '_' + str(sc)
cat_sc_s.append(name)
df[name] = df[(df["category"] == cat) & (df["sub category"] == sc)]["value"]
noDupes = df[["brand", "model", "column1", "column2", "column3"] + cat_sc_s].drop_duplicates().copy()
print(noDupes)
编辑2:
这在****:D中有点痛苦,但在某种程度上它变成了个人的东西:D
import pandas as pd
df = pd.read_csv("abhorrent.csv")
df = df.fillna('')
cats = df["category"].drop_duplicates().tolist()
sub_cats = df["sub category"].drop_duplicates().tolist()
cat_sc_s = []
for cat in cats:
for sc in sub_cats:
if sc == '':
sc = 'blanc'
name = str(cat) + '_' + str(sc)
cat_sc_s.append(name)
df[name] = df[(df["category"] == cat) & (df["sub category"] == sc)]["value"]
df = df.fillna('')
df = df.groupby(["brand", "model", "column1", "column2", "column3"], as_index=False).agg(' '.join)
df = df.drop(['category', 'sub category', 'value'], axis = 1)
print(df)
测试一下,让我知道
但是,它会改变顺序。结果:
您可以执行以下操作:
noDupes['cat1_sc1'] = df[(df["category"] == "cat1") & (df["sub category"] == "sc1")]["value"]
你必须在所有类别和子类别上都这样做,但我想你明白了
编辑:
完整代码以使其全部运行:
import pandas as pd
df = pd.read_csv("abhorrent.csv")
cats = df["category"].drop_duplicates().tolist()
sub_cats = df["sub category"].drop_duplicates().tolist()
cat_sc_s = []
for cat in cats:
for sc in sub_cats:
name = str(cat) + '_' + str(sc)
cat_sc_s.append(name)
df[name] = df[(df["category"] == cat) & (df["sub category"] == sc)]["value"]
noDupes = df[["brand", "model", "column1", "column2", "column3"] + cat_sc_s].drop_duplicates().copy()
print(noDupes)
编辑2:
这在****:D中有点痛苦,但在某种程度上它变成了个人的东西:D
import pandas as pd
df = pd.read_csv("abhorrent.csv")
df = df.fillna('')
cats = df["category"].drop_duplicates().tolist()
sub_cats = df["sub category"].drop_duplicates().tolist()
cat_sc_s = []
for cat in cats:
for sc in sub_cats:
if sc == '':
sc = 'blanc'
name = str(cat) + '_' + str(sc)
cat_sc_s.append(name)
df[name] = df[(df["category"] == cat) & (df["sub category"] == sc)]["value"]
df = df.fillna('')
df = df.groupby(["brand", "model", "column1", "column2", "column3"], as_index=False).agg(' '.join)
df = df.drop(['category', 'sub category', 'value'], axis = 1)
print(df)
测试一下,让我知道
但是,它会改变顺序。结果:
承蒙我的同事
import pandas as pd
import numpy as np
GROUP_BY = ["brand", "model", "column1", "column2", "column3"]
CATEGORY = "category"
SUB_CATEGORY = "sub category"
VALUE = "value"
GROUPING = "grouping"
def combine_model(group):
def combine_value(value):
return value.str.cat(sep=" || ") #in case of multiple values for one category / sub category combination
value = group.groupby(GROUPING)[VALUE].apply(combine_value)
group.loc[:, value.index.tolist()] = value.values
return group
data = pd.read_csv("abhorrent.csv")
for col in GROUP_BY + [SUB_CATEGORY, VALUE]:
data[col].fillna("N/A", inplace=True)
data[GROUPING] = data[CATEGORY] + "_" + data[SUB_CATEGORY]
columns = data[GROUPING].drop_duplicates().tolist()
for col in columns:
data[col] = np.nan
data = data.groupby(GROUP_BY).apply(combine_model)
data.drop_duplicates(subset=GROUP_BY, inplace=True)
Rest只是关于删除不必要的列
感谢所有建议解决方案或留言的人 由我的同事提供
import pandas as pd
import numpy as np
GROUP_BY = ["brand", "model", "column1", "column2", "column3"]
CATEGORY = "category"
SUB_CATEGORY = "sub category"
VALUE = "value"
GROUPING = "grouping"
def combine_model(group):
def combine_value(value):
return value.str.cat(sep=" || ") #in case of multiple values for one category / sub category combination
value = group.groupby(GROUPING)[VALUE].apply(combine_value)
group.loc[:, value.index.tolist()] = value.values
return group
data = pd.read_csv("abhorrent.csv")
for col in GROUP_BY + [SUB_CATEGORY, VALUE]:
data[col].fillna("N/A", inplace=True)
data[GROUPING] = data[CATEGORY] + "_" + data[SUB_CATEGORY]
columns = data[GROUPING].drop_duplicates().tolist()
for col in columns:
data[col] = np.nan
data = data.groupby(GROUP_BY).apply(combine_model)
data.drop_duplicates(subset=GROUP_BY, inplace=True)
Rest只是关于删除不必要的列
感谢所有建议解决方案或留言的人 您熟悉熊猫数据帧的功能吗?例如,
df.pivot(columns='category')
@Antihead,所以我一直在研究pivot函数,它看起来不太好。我在聚合方面有问题。默认情况下,pivot_表似乎需要一个数字类型。当我使用just pivot时,它表示传递值的长度为12,索引意味着5。您熟悉DataFrames的功能吗?例如,df.pivot(columns='category')
@Antihead,所以我一直在研究pivot函数,它看起来不太好。我在聚合方面有问题。默认情况下,pivot_表似乎需要一个数字类型。当我使用just pivot时,它表示传递值的长度为12,索引意味着5。不幸的是,我似乎无法让它工作。当我把它赋给一个变量时,它会正确地返回一个序列<代码>测试=df[(df[“类别”]=“cat1”)&(df[“子类别”]=“sc1”)][“值”]但是,当我尝试将其分配到您建议的新列时,所有值均为nan。可能是因为noDupes df和代码返回的序列长度不同?换句话说,并非所有独特的型号都必须具有cat1+sc1行。是吗?是的,对不起,我弄错了,我自己看到的。见后续编辑无问题。目前正在耐心等待结果。似乎500k行让pandas有了一个赚钱的机会:-P python的行为是否像SQL一样,当运行一个残酷的查询时,它可能永远不会完成?您认为像这样处理500k记录需要多长时间?我什么时候该担心?15-30分钟后?还是更多?编辑:好的,期待编辑。我真的不知道怎么做,对不起,我会把答案留在这里,让任何人最终得到答案!我想我很幸运地得到了它,我似乎无法让它工作。当我把它赋给一个变量时,它会正确地返回一个序列<代码>测试=df[(df[“类别”]=“cat1”)&(df[“子类别”]=“sc1”)][“值”]但是,当我尝试将其分配到您建议的新列时,所有值均为nan。可能是因为noDupes df和代码返回的序列长度不同?换句话说,并非所有独特的型号都必须具有cat1+sc1行。是吗?是的,对不起,我弄错了,我自己看到的。见后续编辑无问题。目前正在耐心等待结果。似乎500k行让pandas有了一个赚钱的机会:-P python的行为是否像SQL一样,当运行一个残酷的查询时,它可能永远不会完成?您认为像这样处理500k记录需要多长时间?我什么时候该担心?15-30分钟后?还是更多?编辑:好的,期待编辑。我真的不知道怎么做,对不起,我会把答案留在这里,让任何人最终得到答案!我想我明白了