获取具有特定值的单元格的列和行标签

时间:2017-12-20 13:32:07

标签: python pandas python-3.6

我有包含交叉引用的CSV文件,这意味着行被标记,列被标记,单元格包含“X”,两者都适用(如果我们谈论糖果,想象使用颜色和味道,所以文件是某种糖果,红色的味道像草莓,绿色的像苹果等,这意味着):

Candy Q     red     green       blue
apple               X
strawberry  X
smurf                           X
dunno lol   X       X           X

我可以将它们加载到pandas数据帧中,读取它们,迭代它们,但我没有设法获取包含X的单元格的描述符。 我已经尝试了三种不同的迭代器pandas提供,但从未得到我需要的地方。我已经尝试使用迭代器并为index-based value-checking增加,但它相当混乱,我放弃了它。

理想情况下,输出为{apple: green},{strawberry: red}, {smurf: blue},{dunno lol: [red, green, blue]}

我如何获得这些references

编辑:我可能需要添加:我不提前知道列名或行名,因为它们不统一,它们遵循一定的逻辑,但一般来说,我无法定义严格的模式。

更新#2:代码,根据coldspeed和Scott Boston的综合解决方案(加上一个微小的修复):

files = glob.glob(mappings_path + '\\*.csv')
# iterate over the list getting each file
for file in files:
    # open each file
    with open(file,'r') as f:
        # read content into pandas dataframe
        df = pd.read_csv(f, delimiter=";", encoding='utf-8')
        # set index to first column (and only column)
        df = df.set_index(df.iloc[:, 0])

        d = defaultdict(list)
        for x, y in zip(*np.where(df.notnull())):
            d[df.index[x]].append(df.columns[y])

        res = dict(d)
        for k, v in res.items():
            del v[0]
        logger.info(res)

修复了每个结果列表中首先出现的描述符(示例中为Candy Q)的问题: {'apple': ['Candy Q','green'], 'strawberry': ['Candy Q','red']等等。 Here's a link to the CSV files in case you need them or want to know what this is about,或the fourth download on this page如果您不信任人们在互联网上发布的链接。

感谢大家的帮助!

2 个答案:

答案 0 :(得分:2)

df

      Candy Q  red green blue
0       apple  NaN     X  NaN
1  strawberry    X   NaN  NaN
2       smurf  NaN   NaN    X
3   dunno lol    X     X    X

df = df.set_index('Candy Q')

稍微hacky,但非常快。

j = df.notnull()\
      .dot(df.columns + '_')\
      .str.strip('_')\
      .str.split('_')\
      .to_dict()

print(j)
{
    "dunno lol": [
        "red",
        "green",
        "blue"
    ],
    "smurf": [
        "blue"
    ],
    "strawberry": [
        "red"
    ],
    "apple": [
        "green"
    ]
} 

这涉及在列和掩码之间执行“点”积(指定单元格是否具有X)。

这里需要注意的是,用于列名称的分隔符(在这种情况下为_ - 下划线)不应作为列名称的一部分存在。在这种情况下,请选择列中不存在的任何分隔符,这应该可以。

答案 1 :(得分:2)

df:

            red green blue
Candy Q                   
apple       NaN     X  NaN
strawberry    X   NaN  NaN
smurf       NaN   NaN    X
dunno lol     X     X    X

您可以使用np.where返回索引:

from collections import defaultdict

d = defaultdict(list)
for x, y in zip(*np.where(df.notnull())):
     d[df.index[x]].append(df.columns[y])

dict(d)

输出:

{'apple': ['green'],
 'dunno lol': ['red', 'green', 'blue'],
 'smurf': ['blue'],
 'strawberry': ['red']}

谢谢@cᴏʟᴅsᴘᴇᴇᴅ,我感谢编辑和简化。