【问题标题】:Creating new columns in a csv file using data from a different csv file使用来自不同 csv 文件的数据在 csv 文件中创建新列
【发布时间】:2019-06-06 05:13:14
【问题描述】:

我有这个数据科学问题,我需要使用两个 csv 文件中提供的信息创建一个测试集。

问题

data1.csv

猫,In1,In2
aaa, 0, 1
aaa, 2, 1
aaa, 2, 0
aab, 3, 2
aab, 1, 2

data2.csv

猫,索引,属性1,属性2
aaa, 0, 150, 450
aaa, 1, 250, 670
aaa, 2, 30, 250
aab, 0, 60, 650
aab, 1, 50, 30
aab, 2, 20, 680
aab, 3, 380, 250

从这两个文件中,我需要一个更新的 data1.csv 文件。在 In1 和 In2 的地方,我需要特定类别(cat)下的特定索引(In1 和 In2)的属性。

注意:特定类别(猫)中的所有索引都有自己的属性

结果应该是这样的,

updated_data1.csv

猫,In1a1,In1a2,In2a1,In2a2
aaa, 150, 450, 250, 670
aaa, 30, 250, 250, 670
aaa, 30, 250, 150, 450
aab, 380, 250, 20, 680
aab, 50, 30, 20, 680

我需要一种在 python 中使用 pandas 来解决这个问题的方法。到目前为止,我已将 csv 文件加载到我的 jupyter 笔记本中。而且我不知道从哪里开始。

请注意,这是我使用 python 进行数据操作的第一周,我对 python 知之甚少。也请原谅我丑陋的格式。我正在用手机输入这个问题。

【问题讨论】:

标签: python pandas csv dataframe


【解决方案1】:

正如其他人所建议的,您可以使用pd.merge。在这种情况下,您需要合并多个列。基本上,您需要定义left DataFrame(此处为data1)中的哪些列映射到right DataFrame(此处为data2)中的哪些列。另见pandas merging 101

# Read the csvs
data1 = pd.read_csv('data1.csv')
data2 = pd.read_csv('data2.csv')
# DataFrame with the in1 columns
df1 = pd.merge(left=data1, right=data2, left_on = ['cat','In1'], right_on = ['cat', 'index'])
df1 = df1[['cat','attribute1','attribute2']].set_index('cat')
# DataFrame with the in2 columns
df2 = pd.merge(left=data1, right=data2, left_on = ['cat','In2'], right_on = ['cat', 'index'])
df2 = df2[['cat','attribute1','attribute2']].set_index('cat')
# Join the two dataframes together.
df = pd.concat([df1, df2], axis=1)
# Name the columns as desired
df.columns = ['in1a1', 'in1a2', 'in2a1', 'in2a2']

通常应该尽量避免遍历 DataFrame,因为它的效率不是很高。但这绝对是一个可能的解决方案。

# Read the csvs
data1 = pd.read_csv('data1.csv')
data2 = pd.read_csv('data2.csv')
# This list will be the data for the resulting DataFrame
rows = []
# Iterate through data1, unpacking values in each row to variables
for idx, cat, in1, in2 in data1.itertuples():
    # Create a dictionary for each row where the keys are the column headers of the future DataFrame
    row = {}
    row['cat'] = cat
    # Pick the correct row from data2
    in1 = (data2['index'] == in1) & (data2['cat'] == cat)
    in2 = (data2['index'] == in2) & (data2['cat'] == cat)
    # Assign the correct values to the keys in the dictionary 
    row['in1a1'] = data2.loc[in1, 'attribute1'].values[0]
    row['in1a2'] = data2.loc[in1, 'attribute2'].values[0]
    row['in2a1'] = data2.loc[in2, 'attribute1'].values[0]
    row['in2a2'] = data2.loc[in2, 'attribute2'].values[0]
    # Append the dictionary to the list
    rows.append(row)
# Construct a DataFrame from the list of dictionaries
df = pd.DataFrame(rows)

【讨论】:

  • 感谢您的冗长解释。但是,当我尝试将其编码为原始问题时,会返回一个错误,提示“解包的值太多(预期为 4)”.. 这背后的原因是什么?另外,您的代码中的 idx 指的是什么?
  • @user6237796 df.itertuples() 遍历 DataFrame 并创建一个元组,其中包含索引和每行的所有值。该错误意味着您的 data1 中的元组具有超过 4 个值,这是您尝试解压缩到的变量数...我使用 idx 来引用 pandas 生成的数字索引csv(因为我没有通过index_col),但在这里并不重要(我不在任何地方使用它)。例如,我可以使用虚拟变量或通过cat 索引data1
  • 当然! No need to say thanks。接受答案就足以说明它对您有用。稍后,您还可以upvote 有用的问题和答案来推动内容更高。
猜你喜欢
  • 2017-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 1970-01-01
  • 2021-07-08
相关资源
最近更新 更多