# Excluding words from a word frequency count

**URL:** https://forums.powershell.org/t/excluding-words-from-a-word-frequency-count/499
**Category:** PowerShell Help
**Created:** [December 31, 2011, 6:30pm UTC](https://forums.powershell.org/t/excluding-words-from-a-word-frequency-count/499 "2011-12-31T18:30:00Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![archives](https://avatars.discourse-cdn.com/v4/letter/a/bb73d2/32.png) [@archives](https://forums.powershell.org/u/archives)
#### Post date: [December 31, 2011, 6:30pm UTC](https://forums.powershell.org/t/excluding-words-from-a-word-frequency-count/499/1 "2011-12-31T18:30:00Z")

</div>

by dwwilson66 at 2013-01-16 06:38:33

> I am developing a PowerShell script to analyze potential document keywords. My plan is to count occurences of unique words and take the top 10 or 15 words. Here’s where I am so far, and I need a hand figuring out how to proceed with my next step–excluding certain words and characters from the result set and word counts.  
> `$srcpath = "c:\users\x46332\desktop\testpath"$docname = "testfile.txt"$document = get-content $srcpath$docname$document = [string]::join(" ", $document) $words = $document.split(" t&quot;,&#91;stringsplitoptions&#93;&#58;&#58;RemoveEmptyEntries) <br>$uniq = $words | sort -uniq <br>$words | % {$wordhash=@{}} {$wordhash&#91;$_&#93; += 1} <br>Write-Host $docname &quot;contains&quot; $wordhash&#46;psbase&#46;keys&#46;count &quot;unique words distributed as follows&#46;&quot;<br>$frequency = $wordhash&#46;psbase&#46;keys | sort {$wordhash&#91;$_&#93;}<br>-1&#46;&#46;-15 | %{$frequency&#91;$_&#93;+&quot; &quot;+$wordhash&#91;$frequency&#91;$_&#93;&#93;}<br>$grouped = $words | group | sort count<br></code><br>My output from this script is as follows, and I've marked examples of the words I want to exclude.<br><code><br>testfile&#46;txt contains 222 unique words distributed as follows&#46;<br>Agency 53<br>Assistance 30<br>of 22 &lt;&lt;&lt;&lt;&lt; exclude<br>to 22 &lt;&lt;&lt;&lt;&lt; exclude<br>in 20 &lt;&lt;&lt;&lt;&lt; exclude<br>Promise 17<br>Enter 11<br>grant 11<br>Click 10 &lt;&lt;&lt;&lt;&lt; exclude<br>the 10 &lt;&lt;&lt;&lt;&lt; exclude<br>button&#46; 9 &lt;&lt;&lt;&lt;&lt; exclude punctuation<br>amount 9<br>box&#46; 9<br>and 8 &lt;&lt;&lt;&lt;&lt; exclude<br>you 8 &lt;&lt;&lt;&lt;&lt; exclude<br></code><br>There are two issues going on here: <br>First, I want to eliminate punctiation, so &quot;button&quot; and &quot;button.&quot; are counted as one unique word. I'm thinking that a regex will achieve that, but I'm not quite sure where to insert that or the proper syntax. I've tried -match [a-zA-Z], -replace (![a-zA-z],&quot; &quot;), [regex]] at various places in the script without any success...I keep getting an error that I can't index into a null array:<br><code><br>Cannot index into a null array&#46;<br>At C&#58;\users\x46332\desktop\testcount&#46;ps1&#58;10 char&#58;25<br>+ -1&#46;&#46;-25 | %{ $frequency&#91; &lt;&lt;&lt;&lt; $_&#93;+&quot; &quot;+$wordhash&#91;$frequency&#91;$_&#93;&#93;}<br> + CategoryInfo &#58; InvalidOperation&#58; (-25&#58;Int32) &#91;&#93;, RuntimeException<br> + FullyQualifiedErrorId &#58; NullArray <br></code><br>How can I make this work? I think I'm lost on the correct syntax, and while it makes sense to me to do the character filter at the get-content or join step, I may be wrong.<br><br>Second, I have an ASCII file containing about 150 &quot;insignificant&quot; words and phrases to be filtered from counts (&quot;excllist.txt&quot;). There is one phrase per line, so they're delimited by a carriage return. My thought is to match that list to the $wordhash table. I can reset the hash value of words appearing my file to 0 and the sort and count functions automatically sort those at the bottom. Alternately, I could just delete those records from the hashtable. I don't know which strategy is better, nor do I know how to make that happen. Anyone have experience with this? Thanks for your help!</blockquote>by nohandle at 2013-01-16 08:45:52<blockquote><strong>Edit]<em>I wrongly use the input variable here which is special variable used to deliver pipeline input to function. Use another variable name instead. Thanks Aleksandar for pointing it out.</em><br>1] Here is solution to the first issue (showing it on small scale so tweek it) <br><code>$input = &#39;three&#39;,&#39;three&#39;,&#39;one&#39;,&#39;three&#39;,&#39;two&#39;,&#39;two&#39; <br>$statistic = $input | foreach -Begin {$hash=@{}} -Process {$hash.$_++} -End {$hash}<br>$statistic.GetEnumerator&#40;&#41; | sort -Property value -Descending | select -First 2</code><br><code>Name Value<br>---- -----<br>three 3 <br>two 2 <br></code></strong></blockquote>by nohandle at 2013-01-16 08:52:11<blockquote>2] here is quick and dirty solution to the . and other characters issue. it just removes any non a-z characters. if you index english pages it should be pretty accurate. To get something more elaborate search regex forums.<br><code>&quot;Hello, this is dog.&quot; -split &#39; &#39; -replace &#39;[^a-z]&#39;</code><br><code>Hello<br>this<br>is<br>dog<br></code></blockquote>by nohandle at 2013-01-16 09:04:57<blockquote><strong>Edit]<em>I wrongly use the input variable here which is special variable used to deliver pipeline input to function. Use another variable name instead. Thanks Aleksandar for pointing it out.</em><br><br>and all of it combined with the list of not permitted words: <br><code>$input = &quot;three is just three when not multiplied by zero and thirteen when you append it to onenand the second line marked by number two" $oneLine = $input -replace "n&quot;<br>$JustAtoZ = $oneLine -replace &#39;[^a-z|]&#39;<br>$words = $JustAtoZ -split &#39; &#39; <br>$statistic = $words | foreach -Begin {$hash=@{}} -Process {$hash.$_++} -End {$hash}<br><br>$notPermittedWords = &#39;one&#39;,&#39;zero&#39;,&#39;by&#39;<br>$notPermittedWords | foreach {<br> if &#40;$statistic.ContainsKey&#40;$_&#41;&#41;<br> {<br> $statistic.Remove&#40;$_&#41;<br> }<br>	}<br>$statistic.GetEnumerator&#40;&#41; | <br>	sort -Property value -Descending | <br> select -First 2</code><br><code>Name Value<br>---- -----<br>three 2 <br>when 2 </code></strong></blockquote>by dwwilson66 at 2013-01-16 10:19:03<blockquote>Awesome. Exactly what I'm looking for. Let me play to make sure I understand how to reproduce it as needed. If I have additional questions, I'll post. :)</blockquote>by dwwilson66 at 2013-01-16 12:35:22<blockquote>I've got a few questions to help me understand...this may get lengthy. :)<br><br>[quote=&quot;nohandle&quot;]<br><code>$input = &quot;three is just three when not multiplied by zero and thirteen when you append it to onenand the second line marked by number two"`[/quote]  
> Instead of hardcoded input, I have a series of files in a directory. My strategy is…  
> `function Count-Words ($inputdoc) {	$srcpath = "c:\users\x46332\desktop\testpath"	$docname = $inputdoc	$document = get-content $srcpath$docname $document = [string]::join(" ", $document) $words = $document.split(" t&quot;,[stringsplitoptions]::RemoveEmptyEntries&#41; <br>	$uniq = $words | sort -uniq <br>	$words | % {$wordhash=@{}} {$wordhash[$_] += 1}<br>	Write-Host $docname &quot;contains&quot; $wordhash.psbase.keys.count &quot;unique words distributed as follows.&quot;<br>	$frequency = $wordhash.psbase.keys | sort {$wordhash[$_]}<br>	-1..-25 | %{ $frequency[$_]+&quot; &quot;+$wordhash[$frequency[$_]]}<br>	$grouped = $words | group | sort count<br>}<br>for-each&#40;$inputdoc in $testpath&#41; {<br>	Count-Words &#40;$inputdoc&#41;<br>}</code>	<br>...which, I assume will be fine for the purposes of this example. I've not tested the for-each logic, but I do know that the script in the function runs just fine as a standalone script. Also, I still need to replace the non-alpha characters with a space, as you demonstrate here. <br>[quote=&quot;nohandle&quot;]<code>$oneLine = $input -replace &quot;n"$JustAtoZ = $oneLine -replace '[^a-z|]'$words = $JustAtoZ -split ' ' $statistic = $words | foreach -Begin {$hash=@{}} -Process {$hash.$++} -End {$hash}`_[/quote]  
> However, I can’t seem to get this code to work when I integrate it with my function above. I would THINK that the -replace would be most appropriate in the [strin]::join line…but it errors out no matter where I put it. That’s where I’m lost.  
> `Method invocation failed because [System.Object[]] doesn’t contain a method named ‘split’.At C:\users\x46332\desktop\testcount3.ps1:21 char:36+ $exclwords = $exclusionAlpha.split <<<< (",",[stringsplitoptions]::RemoveEmptyEntries) + CategoryInfo : InvalidOperation: (split:String) [], RuntimeException + FullyQualifiedErrorId : MethodNotFoundIndex operation failed; the array index evaluated to null.At C:\users\x46332\desktop\testcount3.ps1:23 char:44+ $exclwords | % {$exclhash=@{}} {$exclhash[<<<< $`_`] +=1} + CategoryInfo : InvalidOperation: (🙂 , RuntimeException + FullyQualifiedErrorId : NullArrayIndex`   
>   
> My SECOND part is to take an ASCII text file of 174 words to be excluded. Originally I’d thought to create and compare two hashtables, but I like the idea of comparing the words on the fly with a nested for-each loop. I’m thinking I can create a function that will open my exclusion list (…can I just declare $notPermittedWords = gc $exclpath instead of the hardcoded word list you have noted below…)? I would call that function from within the WordCount function, passing the $words variable to compare to the open exclusion list. Does that make sense?   
> [quote="nohandle"]  
> `$notPermittedWords = 'one','zero','by'$notPermittedWords | foreach {if ($statistic.ContainsKey($)){$statistic.Remove($)}}$statistic.GetEnumerator() | sort -Property value -Descending | select -First 2`  
> "[/powershell][/quote]  
>   
> Thanks for your help!

by nohandle at 2013-01-16 13:03:43

> **Edit]_I wrongly use the input variable here which is special variable used to deliver pipeline input to function. Use another variable name instead. Thanks Aleksandar for pointing it out._**  
>   
> **All of this I kept in mind when I wrote the script. There is pretty much nothing you need to change to analyze files and load the words to exclude from file.   
> just load the files to variables and change the first -replace to replace new lines with spaces (you could use single line option of the regex but this is easier)  
> `$input = Get-Content c:\temp\wordCount.txt$notPermittedWords = Get-Content c:\temp\exclude.txt#make the file a long single line by replacing the newlines $oneLine = $input -replace "n&quot;,&#39; &#39;</code><br><br>And of course remove the line where you list the notPermittedWords<br><code>$notPermittedWords = &#39;one&#39;,&#39;zero&#39;,&#39;by&#39;</code><br>Just analyzed part of the wikipedia Powershell page and it works like a charm.<br><code>Name Value <br>---- ----- <br>PowerShell 15 <br>Windows 10 <br>to 6 <br>cmdlets 5 <br>and 5 <br>by 5 </code><br>Looks like I have to add &quot;to&quot;, &quot;and&quot; and &quot;by&quot; to my exclude list.<br><br>Converting it to a function should be piece of cake :)</strong></blockquote>by nohandle at 2013-01-16 13:31:29<blockquote><code>function Get-WordCount {<br>	[CmdletBinding&#40;&#41;]<br>	param<br>	&#40;<br> [Parameter&#40;Mandatory=$True,<br> ValueFromPipeline=$True&#41;]<br> [string[]]$Text,<br><br> [string[]]$Exclude<br>	&#41;<br>	process <br>	{ <br> $collected += $text <br>	}	<br>	end	{<br> #make the file a long single line by replacing the newlines <br> $oneLine = $collected -replace &quot;n",' ' $JustAtoZ = $oneLine -replace '[^a-z|]' $words = $JustAtoZ -split ' ' $statistic = $words | foreach -Begin {$hash=@{}} -Process {$hash.$++} -End {$hash} if ($exclude) { $exclude | foreach { if ($statistic.ContainsKey($)) { $statistic.Remove($_) } } } $statistic.GetEnumerator() | sort -Property value -Descending }}Get-Content c:\temp\wordCount.txt | Get-WordCount -Exclude (Get-Content c:\temp\exclude.txt) | select -First 15`**

---

<div class="post-metadata">

### Author: ![dotnVo](https://avatars.discourse-cdn.com/v4/letter/d/4af34b/32.png) [@dotnVo](https://forums.powershell.org/u/dotnVo)
#### Post date: [May 16, 2024, 8:57pm UTC](https://forums.powershell.org/t/excluding-words-from-a-word-frequency-count/499/2 "2024-05-16T20:57:55Z")

</div>


